Ř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 catvá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 catvypíše "ahoj" a okamžitě skončí, protožecatvš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 catvám dá prázdný řádek, ale pokud zkusíte napsat "ahoj", nedostanete žádnou ozvěnu. Je to proto, že zatímcocatje 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 cattaké 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 -pzobrazí výzvu k zadání hesla. Pokud zadáte heslo, znaky se vytisknou viditelně.docker run -i alpine shvám dá prázdný řádek. Pokud zadáte příkaz jakolsdostanete 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
-iani-tmožnosti) kontejner Docker odešle svůj výstup pouze do STDOUT, - s
-imožnost přichází připojení k STDIN, -tvolba 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.