To polecenie działa:
$ echo 'hi there' | docker run -i ubuntu cat
hi there
To polecenie odpowiada komunikatem o błędzie:
$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY
Chciałbym dowiedzieć się dokładnie, co się tutaj dzieje. Nie tylko „usuń -t i zostanie to naprawione”.
Wiem, że docker run
„s -t
opcja oznacza«Przydzielanie pseudo-TTY», i czytałem historycznych przeglądy co stoi na TTY , ale to nie pomogło mi zrozumieć, jaki rodzaj umowy jest naruszone tutaj.
-t
, ale nie mogę zmodyfikować polecenia startu dokera w produkcji. Muszę więc sprawić, by aplikacja zaczęła myśleć-t
.Odpowiedzi:
Ta odpowiedź pomogła mi owinąć głowę:
-i
ani-t
opcji) kontener Docker wysyła dane wyjściowe do STDOUT,-i
opcją jest połączenie ze STDIN,-t
opcja pobiera sterownik interfejsu terminala , który działa na STDIN / STDOUT. A kiedy wciągnięty jest sterownik terminalu, komunikacja z kontenerem musi być zgodna z protokołem interfejsu terminalu . Rurociągi łańcucha nie.źródło
Późna odpowiedź, ale może komuś pomóc
docker run/exec -i
połączy STDIN polecenia wewnątrz kontenera z STDINdocker 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 procescat
czeka na dane wejściowe ze strumienia nieskończonego, który jest wejściem końcowym plikudocker run
.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 przypadkachcat
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ściacat
.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, żecat
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 gocat
. 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ściemdocker run
jest potok z poprzedniego echa, a nie terminal, w którymdocker run
jest wykonywanyNa koniec, dlaczego musiałbyś zdać,
-t
jeśli-i
podołasz, aby połączyć swój wkład zcat
wejściem? Jest tak, ponieważ polecenia traktują dane wejściowe inaczej, jeśli jest to terminal. Najlepiej ilustruje to również przykładdocker 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 jakls
otrzymasz wynik, ale nie pojawi się monit lub kolorowe wyjście.W dwóch ostatnich przypadkach, masz ten problem, bo
mysql
jakshell
nie traktowali jako wejście tty, a zatem nie używać tty specyficzne zachowanie jak maskowanie wejścia lub kolorowania wyjście.źródło
Tty oznacza, że masz terminal, coś, co może zapewnić xterm lub jeden z wielu interfejsów linii poleceń Linux. Potrzebuje powiązanego z nim interfejsu klawiatury i wyjścia tekstowego. Typowe powody, dla których warto to robić, to obsługa kolorowego tekstu wyjściowego, obsługa różnych kombinacji klawiszy (takich jak klawisze strzałek) i możliwość przesuwania kursora po ekranie.
Kiedy potokujesz polecenie do okna dokowanego, tak jak w
echo
przykładzie, ten potok jest wejściem, a potok nie ma interfejsu tty, to tylko strumień tekstu. Próba utworzenia tty z tym zakończy się niepowodzeniem, jak wskazuje komunikat o błędzie.źródło