Что именно делает эта опция? Я много читал на TTY и все еще в замешательстве. Я играл с отсутствием -t
и просто, -i
и кажется, что программы, которые ожидают пользовательского ввода, выдают ошибку без -t
. Почему важно включить псевдо-TTY?
Что именно делает эта опция? Я много читал на TTY и все еще в замешательстве. Я играл с отсутствием -t
и просто, -i
и кажется, что программы, которые ожидают пользовательского ввода, выдают ошибку без -t
. Почему важно включить псевдо-TTY?
Ответы:
-t
Вариант идет к тому, как Unix / Linux обрабатывает терминальный доступ. В прошлом терминал был жестким соединением, позже модемным соединением. У них были драйверы для физических устройств (они были настоящими частями оборудования). Как только обобщенные сети начали использоваться, был разработан драйвер псевдо-терминала. Это потому, что это создает разделение между пониманием того, какие возможности терминала можно использовать, без необходимости записывать их непосредственно в вашу программу (читайте справочные страницы stty
, curses
).
Итак, с этим в качестве фона, запустите контейнер без параметров, и по умолчанию у вас есть поток stdout (так docker run | <cmd>
работает); запустить с -i
, и вы получите поток stdin (так <cmd> | docker run -i
работает); используйте -t
, как правило, в комбинации, -it
и у вас есть добавленный драйвер терминала, который, если вы взаимодействуете с процессом, скорее всего, то, что вы хотите. Это в основном делает начало контейнера похожим на сеанс терминального соединения.
docker run -i ubuntu
и docker run -it ubuntu
вы увидите разницу сразу. «-i» позволяет заставить контейнер ожидать взаимодействия с хостом, но фактическое взаимодействие с консолью (терминалом) возможно после того, как вы «выделите tty драйвер» с флагом «-t».
-t
, но я не запускаю докер , но не могу изменить команду запуска докера в рабочей среде. Поэтому мне нужно заставить приложение думать, что оно было начато -t
.
Поздний ответ, но может помочь кому-то
docker run/exec -i
соединит STDIN команды внутри контейнера с STDIN docker run/exec
самого.
Так
docker run -i alpine cat
выдает пустую строку в ожидании ввода. Типа "привет", вы получаете эхо "привет". Контейнер не выйдет, пока вы не отправите CTRL+, Dпотому что основной процесс cat
ожидает ввода от бесконечного потока, который является входом терминала для docker run
.echo "hello" | docker run -i alpine cat
, напечатает «привет» и сразу же 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
вместе. Это говорит cat, что его вход является терминалом, и в то же время подключите этот терминал к входу 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 -u root -p
даст вам запрос пароля. Если вы введете пароль, символы будут напечатаны визуально.docker run -i alpine sh
даст вам пустую строку. Если вы наберете команду, как ls
вы получите вывод, но вы не получите приглашение или цветной вывод.В последних двух случаях вы получаете это поведение, потому mysql
что вы shell
не обрабатываете ввод как tty и, следовательно, не используете специфическое для tty поведение, такое как маскирование ввода или окрашивание вывода.
-t
и -i
варианты делают!
-t
Аргумент не документирован хорошо, или упоминается многими людьми , часто, по данным поиска Google.
Он даже не отображается, когда вы выводите список (что должно быть) всех аргументов докер-клиента, набирая docker
в приглашении Bash (с последней версией 1.8.1).
На самом деле, если вы попытаетесь получить конкретную помощь по этому аргументу, набрав docker -t --help
if , вы получите удивительно смутный ответ:
флаг указан, но не определен: -t
Таким образом, вы не можете быть обвинены в том, что запутались в этом аргументе!
В онлайн-документации Docker есть упоминание о том, что оно «выделяет псевдо-tty» и часто используется с -i
:
https://docs.docker.com/reference/run/
Я видел, что он использовался в документации для потрясающего jwilder/nginx-proxy
док-контейнера следующим образом:
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
В этом случае он отправляет выходные данные в «virtual» tty (командная строка / терминал Bash) в этом контейнере Docker. Затем вы можете увидеть эти выходные данные, выполнив команду docker docker logs CONTAINER
где CONTAINER
первая пара символов идентификатора этого контейнера. Этот идентификатор контейнера можно найти, набравdocker ps -a
Я видел этот -t
аргумент кратко упоминается в следующей ссылке, где он говорит
-t
И-i
флаги выделить псевдо-терминал и держать стандартный ввод открытым , даже если не прилагается. Это позволит вам использовать контейнер как традиционную виртуальную машину, пока работает приглашение bash.
https://coreos.com/os/docs/latest/getting-started-with-docker.html
Надеюсь, это поможет! Я не уверен, почему это не задокументировано или не используется много. Возможно, это экспериментально и будет реализовано как документированная функция в следующих версиях.
docker run --help
, а не docker -t --help
: -t, --tty=false Allocate a pseudo-TTY
"
Что я знаю о -t
следующем:
docker exec -ti CONTAINER bash
- позволяет мне «войти» в контейнер. Это похоже на ssh-ing (это не так).
Но беда была, когда я захотел восстановить базу данных.
Обычно я делаю docker exec -ti mysql.5.7 mysql
- здесь я выполняю команду mysql в контейнере и получаю интерактивный терминал.
Я добавил <dump.sql
к предыдущей команде, чтобы я мог восстановить БД. Но это не удалось с cannot enable tty mode on non tty input
.
Удаление -t
помогло. Все еще не понимаю, почему:
docker exec -i mysql.5.7 mysql < dump.sql
Последний работает. Надеюсь, что это помогает людям.
-t
, но я не запускаю докер , но не могу изменить команду запуска докера в рабочей среде. Поэтому мне нужно заставить приложение думать, что оно было начато -t
.
Каждый процесс имеет три потоки данных ИЭ STDIN/ STDOUT/ STDERR
. Когда процесс выполняется в контейнере, по умолчанию терминал связан с потоком STDOUT процесса, выполняющегося в контейнере. Следовательно, все выходные потоки будут видны при запуске docker run
команды в терминале. Но если вы хотите обеспечить ввод для запущенного процесса в контейнере, то вам нужно соединиться с каналом STDIN процесса, который не является по умолчанию и выполняется docker run -i
командой.
-t
используется для интерактивных / форматированных операций ввода.
-it
Инструктирует DOCKER выделить псевдо-TTY , соединенную с стандартным вводом контейнера, создавая интерактивную оболочку Баша в контейнере.
--interactive
, -i
false
Keep STDIN открыть , даже если не прилагается
--tty
, -t
false
Выделяют псевдо-TTY
-it
флагов.