Поздний ответ, но может помочь кому-то
docker run/exec -i
соединит STDIN команды внутри контейнера с STDIN docker run/exec
самого.
Так
docker run -i alpine cat
выдает пустую строку в ожидании ввода. Типа "привет", вы получаете эхо "привет". Контейнер не выйдет, пока вы не отправите CTRL + D, потому что основной процесс cat
ожидает ввода из бесконечного потока, который является входом терминала для docker run
.
- С другой стороны
echo "hello" | docker -i run alpine cat
, выведите «hello» и немедленно cat
выйдете, потому что замечает, что поток ввода закончился и завершает сам.
Если вы попытаетесь docker ps
после выхода из любого из вышеперечисленных, вы не найдете никаких работающих контейнеров. В обоих случаях cat
само завершение работы завершилось, поэтому docker завершил работу контейнера.
Теперь для "-t" это говорит главному процессу внутри докера, что его вход является терминальным устройством.
Так
docker run -t alpine cat
выдаст пустую строку, но если вы попытаетесь напечатать "привет", вы не получите никакого эха. Это потому, что хотя cat
он подключен к входу терминала, этот вход не подключен к вашему входу. «Привет», который вы ввели, не дошел до ввода cat
. cat
ждет ввода, который никогда не поступит.
echo "hello" | docker run -t alpine cat
также даст вам пустую строку и не выйдет из контейнера на CTRL-D, но вы не получите эхо "привет", потому что вы не прошли -i
Если вы отправите CTRL + C, вы вернете свою оболочку, но если вы попробуете docker ps
сейчас, вы увидите, что cat
контейнер все еще работает. Это потому, что cat
все еще ожидает входной поток, который никогда не был закрыт. Я не нашел никакого полезного использования для -t
одиночества, не будучи объединенным с -i
.
Теперь -it
вместе. Это говорит кошке, что ее вход является терминалом и в то же время подключите этот терминал к входу docker run
которого является терминалом. docker run/exec
прежде чем передать его, убедитесь, что его собственный ввод является tty cat
. Вот почему вы получите, input device is not a TTY
если попытаетесь, echo "hello" | docker run -it alpine cat
потому что в этом случае вход docker run
сам по себе является каналом от предыдущего эха, а не терминалом, где docker run
выполняется
Наконец, зачем вам нужно проходить, -t
если вам нужно -i
будет соединить ваш вход cat
со входом? Это потому, что команды обрабатывают ввод по-разному, если это терминал. Это также лучше всего иллюстрируется на примере
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
даст вам запрос пароля. Если вы введете пароль, символы будут напечатаны визуально.
docker run -i alpine sh
даст вам пустую строку. Если вы наберете команду, как ls
вы получите вывод, но вы не получите приглашение или цветной вывод.
В последних двух случаях вы получаете это поведение, потому mysql
что вы shell
не обрабатываете ввод как tty и, следовательно, не используете специфическое для tty поведение, такое как маскирование ввода или окрашивание вывода.