Это команда, которая работает:
$ echo 'hi there' | docker run -i ubuntu cat
hi there
Это команда, которая отвечает сообщением об ошибке:
$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY
Я хотел бы выяснить, что именно здесь происходит. Не просто «удалить -t, и это будет исправлено».
я знаю это docker run
с -t
вариант означает «Назначить псевдо-TTY», и я прочитал исторические обзоры того, что обозначает TTY, но это не помогло мне понять, какой здесь договор нарушается.
Поздний ответ, но может кому-то помочь
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
напечатает "привет" и немедленно выйдет, потому что cat
замечает, что входной поток закончился, и завершает свою работу.Если вы попытаетесь docker ps
после выхода из любого из вышеперечисленных контейнеров запущенных не будет. В обоих случаях, cat
сам завершил работу, поэтому докер завершил работу контейнера.
Теперь для "-t" это говорит главному процессу внутри докера, что его ввод является терминальным устройством.
Так
docker run -t alpine cat
выдаст вам пустую строку, но если вы попытаетесь ввести «hello», вы не получите никакого эха. Это потому, что пока 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 поведение, такое как маскирование ввода или раскрашивание вывода.
Этот ответ помогло мне обернуться:
-i
ни -t
options) контейнер Docker только отправляет свой вывод в STDOUT,-i
опция идет подключение к STDIN,-t
опция включает драйвер интерфейса терминала, который работает поверх STDIN / STDOUT. И когда втягивается драйвер терминала, связь с контейнером должна соответствовать протокол интерфейса терминала. Обвязка струны - нет.Tty означает, что у вас есть терминал, который может быть предоставлен xterm или одним из многих интерфейсов командной строки linux. Ему нужна клавиатура и связанный с ним интерфейс вывода текста. Типичные причины, по которым это нужно, - поддержка вывода цветного текста, обработка различных комбинаций клавиш (например, клавиш со стрелками) и возможность перемещать курсор по экрану.
Когда вы передаете команду в докер, например, ваш echo
Пример показывает, что канал является входом, и этот канал не имеет интерфейса tty, это просто поток текста. Попытка создать tty с этим не удастся, как указано в сообщении об ошибке.