Пізня відповідь, але може комусь допомогти
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
дасть вам порожній рядок, але якщо ви спробуєте набрати "привіт", ви не отримаєте відлуння. Це тому, що, хоча 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 -uroot -p
надасть вам запит на пароль. Якщо ви введете пароль, символи друкуються помітно.
docker run -i alpine sh
дасть вам порожній рядок. Якщо ви введете команду, як ls
ви отримаєте вихід, але ви не отримаєте підказку або кольоровий вихід.
В останніх двох випадках ви отримуєте таку поведінку, оскільки mysql
так само shell
не трактували вхід як tty і, таким чином, не використовували tty специфічну поведінку, як маскування введення чи забарвлення виводу.