Późna odpowiedź, ale może komuś pomóc
docker run/exec -i
połączy STDIN polecenia wewnątrz kontenera z STDIN docker run/exec
samego.
Więc
docker run -i alpine cat
daje pustą linię czekającą na dane wejściowe. Wpisz „cześć”, otrzymasz echo „cześć”. Kontener nie zostanie zamknięty, dopóki nie wyślesz CTRL + D, ponieważ główny proces cat
czeka na dane wejściowe ze strumienia nieskończonego, który jest wejściem końcowym pliku docker run
.
- Z drugiej strony
echo "hello" | docker -i run alpine cat
wypisuje „cześć” i kończy natychmiast, ponieważ cat
zauważa, że strumień wejściowy zakończył się i sam się kończy.
Jeśli spróbujesz docker ps
po wyjściu z jednego z powyższych, nie znajdziesz żadnych uruchomionych kontenerów. W obu przypadkach cat
samo się zakończyło, więc doker zakończył kontener.
Teraz dla „-t” mówi to głównemu procesowi wewnątrz dokera, że jego wejście jest urządzeniem końcowym.
Więc
docker run -t alpine cat
da ci pustą linię, ale jeśli spróbujesz wpisać „cześć”, nie usłyszysz żadnego echa. Wynika to z faktu, że chociaż cat
jest on podłączony do wejścia terminala, to wejście nie jest podłączone do twojego wejścia. Wpisane słowo „cześć” nie dotarło do wejścia cat
. cat
czeka na dane wejściowe, które nigdy nie docierają.
echo "hello" | docker run -t alpine cat
da ci również pustą linię i nie opuści kontenera na CTRL-D, ale nie dostaniesz echa „cześć”, ponieważ nie przeszedłeś -i
Jeśli wyślesz CTRL + C, odzyskasz swoją powłokę, ale jeśli spróbujesz docker ps
teraz, zobaczysz, że cat
kontener nadal działa. Jest tak, ponieważ cat
wciąż czeka na strumień wejściowy, który nigdy nie został zamknięty. Nie znalazłem żadnego przydatnego zastosowania dla -t
samego bez połączenia -i
.
Teraz -it
razem. Mówi to kotowi, że jego wejściem jest terminal i jednocześnie podłącz ten terminal do wejścia, docker run
którego terminalem jest. docker run/exec
upewni się, że jego dane wejściowe są w rzeczywistości tty przed przekazaniem go cat
. Dlatego dostaniesz a, input device is not a TTY
jeśli spróbujesz, echo "hello" | docker run -it alpine cat
ponieważ w tym przypadku wejściem docker run
jest potok z poprzedniego echa, a nie terminal, w którym docker run
jest wykonywany
Na koniec, dlaczego musiałbyś zdać, -t
jeśli -i
podołasz, aby połączyć swój wkład z cat
wejściem? Jest tak, ponieważ polecenia traktują dane wejściowe inaczej, jeśli jest to terminal. Najlepiej ilustruje to również przykład
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
wyświetli monit o hasło. Jeśli wpiszesz hasło, znaki zostaną wydrukowane w widoczny sposób.
docker run -i alpine sh
da ci pustą linię. Jeśli wpiszesz polecenie, tak jak ls
otrzymasz wynik, ale nie pojawi się monit lub kolorowe wyjście.
W dwóch ostatnich przypadkach, masz ten problem, bo mysql
jak shell
nie traktowali jako wejście tty, a zatem nie używać tty specyficzne zachowanie jak maskowanie wejścia lub kolorowania wyjście.