Řešení 1:
Pozdní odpověď, ale mohla by někomu pomoci
docker run/exec -i
propojí STDIN příkazu uvnitř kontejneru s STDIN z docker run/exec
sám.
Takže
docker run -i alpine cat
vám poskytne prázdný řádek čekající na zadání. Napište „ahoj“, dostanete echo „ahoj“. Kontejner se neukončí, dokud nepošlete CTRL+D, protože hlavní procescat
čeká na vstup z nekonečného proudu, který je terminálovým vstupemdocker run
.- Na druhou stranu
echo "hello" | docker -i run alpine cat
vypíše "ahoj" a okamžitě skončí, protožecat
všimne si, že vstupní proud skončil a sám se ukončí.
Pokud zkusíte docker ps
po opuštění některé z výše uvedených možností nenajdete žádné běžící kontejnery. V obou případech cat
sám se ukončil, takže docker ukončil kontejner.
Nyní pro "-t" toto sděluje hlavnímu procesu uvnitř dockeru, že jeho vstupem je koncové zařízení.
Takže
docker run -t alpine cat
vám dá prázdný řádek, ale pokud zkusíte napsat "ahoj", nedostanete žádnou ozvěnu. Je to proto, že zatímcocat
je připojen k terminálovému vstupu, tento vstup není připojen k vašemu vstupu. "Ahoj", které jste zadali, nedosáhlo vstupucat
.cat
čeká na vstup, který nikdy nedorazí.echo "hello" | docker run -t alpine cat
také vám dá prázdný řádek a neopustí kontejner pomocí CTRL-D, ale nedostanete echo "ahoj", protože jste neprošli-i
Pokud pošlete CTRL+C, dostanete svůj shell zpět, ale pokud zkusíte docker ps
nyní vidíte cat
kontejner stále běží. Důvodem je cat
stále čeká na vstupní proud, který nebyl nikdy uzavřen. Nenašel jsem žádné užitečné použití pro -t
samostatně bez kombinace s -i
.
Nyní za -it
spolu. Tím sdělíte kočce, že její vstup je terminál, a zároveň tento terminál připojte ke vstupu docker run
což je terminál. docker run/exec
se ujistí, že jeho vlastní vstup je ve skutečnosti tty, než jej předá cat
. To je důvod, proč dostanete input device is not a TTY
pokud zkusíte echo "hello" | docker run -it alpine cat
protože v tomto případě vstup docker run
sám je roura z předchozího echa a ne terminál kde docker run
se provede
Nakonec, proč byste měli předat -t
pokud -i
bude stačit připojení vašeho vstupu k cat
vstup? Je to proto, že příkazy zacházejí se vstupem jinak, pokud se jedná o terminál. Nejlépe to ilustruje příklad
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
zobrazí výzvu k zadání hesla. Pokud zadáte heslo, znaky se vytisknou viditelně.docker run -i alpine sh
vám dá prázdný řádek. Pokud zadáte příkaz jakols
dostanete výstup, ale nedostanete výzvu ani barevný výstup.
V posledních dvou případech je toto chování způsobeno mysql
stejně jako shell
nezacházeli se vstupem jako s tty, a proto nepoužívali chování specifické pro tty, jako je maskování vstupu nebo obarvení výstupu.
Řešení 2:
Tato odpověď mi pomohla otočit hlavu:
- ve výchozím nastavení (bez
-i
ani-t
možnosti) kontejner Docker odešle svůj výstup pouze do STDOUT, - s
-i
možnost přichází připojení k STDIN, -t
volba stáhne ovladač terminálového rozhraní , který funguje nad STDIN/STDOUT. A když je zatažen ovladač terminálu, komunikace s kontejnerem musí odpovídat protokolu terminálového rozhraní. Potrubí řetězce ne.
Řešení 3:
Tty znamená, že máte terminál, něco, co by poskytl xterm nebo jedno z mnoha linuxových rozhraní příkazového řádku. Potřebuje klávesnici a rozhraní pro výstup textu. Typickými důvody, proč to chtít, je podpora barevného textového výstupu, ovládání různých kombinací kláves (jako jsou šipky) a možnost pohybovat kurzorem po obrazovce.
Když do dockeru vložíte příkaz, jako je vaše echo
příklad ukazuje, že roura je vstup a ta roura nemá rozhraní tty, je to jen proud textu. Pokus o vytvoření tty s tím selže, jak ukazuje chybová zpráva.