Это команда, которая работает:
$ 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
«S -t
опция означает„Выделяют псевдо-TTY“, и я читал исторические обзоры о том, что стоит TTY для , но это не помогло мне понять , какой вид договора нарушается здесь.
-t
, но я не запускаю докер , но не могу изменить команду запуска докера в рабочей среде. Поэтому мне нужно заставить приложение думать, что оно было начато-t
.Ответы:
Этот ответ помог мне обернуть голову:
-i
и-t
параметров) контейнер Docker отправляет свой вывод только в STDOUT,-i
опцией приходит подключение к STDIN,-t
опция загружает драйвер интерфейса терминала , который работает поверх STDIN / STDOUT. А когда подключается драйвер терминала, связь с контейнером должна соответствовать протоколу интерфейса терминала . Обвязка строки не делает.источник
Поздний ответ, но может помочь кому-то
docker run/exec -i
соединит STDIN команды внутри контейнера с STDINdocker 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
прежде чем передать его, убедитесь, что его собственный ввод является ttycat
. Вот почему вы получите,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 поведение, такое как маскирование ввода или окрашивание вывода.источник
Tty указывает, что у вас есть терминал, который будет предоставлен xterm или одним из многих интерфейсов командной строки linux. Требуется клавиатура и связанный с ним интерфейс вывода текста. Типичные причины для этого - поддержка вывода цветного текста, обработка различных комбинаций клавиш (например, клавиш со стрелками) и возможность перемещать курсор по экрану.
Когда вы передаете команду в docker, как
echo
показано в вашем примере, этот канал является входным, а этот канал не имеет интерфейса tty, это просто поток текста. Попытка создать tty с этим потерпит неудачу, как указывает сообщение об ошибке.источник