Пізня відповідь, але може комусь допомогти
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 специфічну поведінку, як маскування введення чи забарвлення виводу.