Поздний ответ, но может помочь кому-то
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 поведение, такое как маскирование ввода или окрашивание вывода.