Что именно делает эта опция? Я много читал на TTY и все еще в замешательстве. Я играл с отсутствием -t
и просто, -i
и кажется, что программы, которые ожидают пользовательского ввода, выдают ошибку без -t
. Почему важно включить псевдо-TTY?
-t
Вариант идет к тому, как Unix / Linux обрабатывает терминальный доступ. В прошлом терминал был жестким соединением, позже модемным соединением. У них были драйверы для физических устройств (они были настоящими частями оборудования). Как только обобщенные сети начали использоваться, был разработан драйвер псевдо-терминала. Это потому, что это создает разделение между пониманием того, какие возможности терминала можно использовать, без необходимости записывать их непосредственно в вашу программу (читайте справочные страницы stty
, curses
).
Итак, с этим в качестве фона, запустите контейнер без параметров, и по умолчанию у вас есть поток stdout (так docker run | <cmd>
работает); запустить с -i
, и вы получите поток stdin (так <cmd> | docker run -i
работает); используйте -t
, как правило, в комбинации, -it
и у вас есть добавленный драйвер терминала, который, если вы взаимодействуете с процессом, скорее всего, то, что вы хотите. Это в основном делает начало контейнера похожим на сеанс терминального соединения.
-it
флагов.docker run -i ubuntu
иdocker run -it ubuntu
вы увидите разницу сразу. «-i» позволяет заставить контейнер ожидать взаимодействия с хостом, но фактическое взаимодействие с консолью (терминалом) возможно после того, как вы «выделите tty драйвер» с флагом «-t».-t
, но я не запускаю докер , но не могу изменить команду запуска докера в рабочей среде. Поэтому мне нужно заставить приложение думать, что оно было начато-t
.Поздний ответ, но может помочь кому-то
docker run/exec -i
соединит STDIN команды внутри контейнера с STDINdocker 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
прежде чем передать его, убедитесь, что его собственный ввод является 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 -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 , вы получите удивительно смутный ответ:Таким образом, вы не можете быть обвинены в том, что запутались в этом аргументе!
В онлайн-документации Docker есть упоминание о том, что оно «выделяет псевдо-tty» и часто используется с
-i
:https://docs.docker.com/reference/run/
Я видел, что он использовался в документации для потрясающего
jwilder/nginx-proxy
док-контейнера следующим образом:В этом случае он отправляет выходные данные в «virtual» tty (командная строка / терминал Bash) в этом контейнере Docker. Затем вы можете увидеть эти выходные данные, выполнив команду docker
docker logs CONTAINER
гдеCONTAINER
первая пара символов идентификатора этого контейнера. Этот идентификатор контейнера можно найти, набравdocker ps -a
Я видел этот
-t
аргумент кратко упоминается в следующей ссылке, где он говорит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
помогло. Все еще не понимаю, почему:Последний работает. Надеюсь, что это помогает людям.
источник
-t
, но я не запускаю докер , но не могу изменить команду запуска докера в рабочей среде. Поэтому мне нужно заставить приложение думать, что оно было начато-t
.В Linux, когда вы запускаете команду, вам нужен терминал (tty) для ее выполнения.
Поэтому, когда вы хотите подключиться к Docker (или запустить команду в Docker-контейнере), вы должны указать параметр -t, который учитывает наличие терминала в Docker-контейнере.
источник
Каждый процесс имеет три потоки данных ИЭ
STDIN/ STDOUT/ STDERR
. Когда процесс выполняется в контейнере, по умолчанию терминал связан с потоком STDOUT процесса, выполняющегося в контейнере. Следовательно, все выходные потоки будут видны при запускеdocker run
команды в терминале. Но если вы хотите обеспечить ввод для запущенного процесса в контейнере, то вам нужно соединиться с каналом STDIN процесса, который не является по умолчанию и выполняетсяdocker run -i
командой.-t
используется для интерактивных / форматированных операций ввода.источник
-it
Инструктирует DOCKER выделить псевдо-TTY , соединенную с стандартным вводом контейнера, создавая интерактивную оболочку Баша в контейнере.--interactive
,-i
false
Keep STDIN открыть , даже если не прилагается--tty
,-t
false
Выделяют псевдо-TTYhttps://docs.docker.com/engine/reference/commandline/run/
источник