Назад | Перейти на главную страницу

Что в точности означает «устройство ввода не TTY» в выводе «docker run»?

Это команда, которая работает:

$ 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 с этим не удастся, как указано в сообщении об ошибке.