Що саме робить цей варіант? Я багато читав на 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
сам припинився, таким чином докер припинив контейнер.
Тепер для "-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
переконайтесь, що його власний вклад є насправді десятки перед тим, як передавати його 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
чи дає це дивовижно невиразний відповідь:
прапор надається, але не визначено: -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
У цьому випадку те, що він робить, - це надіслати висновок до 'віртуального' tty (командна строка / термінал Bash) в цьому контейнері докера. Потім ви можете побачити цей вихід, виконавши команду docker docker logs CONTAINER
деCONTAINER
є перша пара символів ідентифікатора цього контейнера. Цей ідентифікатор CONTAINER можна знайти, ввівшиdocker ps -a
Цей -t
аргумент я коротко бачив у наступному посиланні, де він говорить
-t
І-i
прапори виділити псевдо-термінал і тримати стандартний ввід відкритим , навіть якщо не додається. Це дозволить вам використовувати контейнер, як традиційний VM, поки запущено запит 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
до попередньої команди, щоб я міг відновити db. Але це не вдалося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
Тримайте STDIN відкритим, навіть якщо він не встановлений
--tty
, -t
false
Виділіть псевдо-TTY
-it
прапорів.