Lösung 1:
Späte Antwort, könnte aber jemandem helfen
docker run/exec -i
verbindet die STDIN des Befehls innerhalb des Containers mit der STDIN von docker run/exec
selbst.
Also
docker run -i alpine cat
gibt Ihnen eine leere Zeile, die auf Eingaben wartet. Geben Sie "Hallo" ein, Sie erhalten ein Echo "Hallo". Der Container wird erst beendet, wenn Sie STRG+D senden, da der Hauptprozesscat
wartet auf Eingaben aus dem unendlichen Strom, der die Terminaleingabe vondocker run
ist .- Andererseits
echo "hello" | docker -i run alpine cat
wird "Hallo" ausgeben und sofort beendet, weilcat
merkt, dass der Eingabestrom beendet ist und beendet sich selbst.
Wenn Sie docker ps
versuchen Nachdem Sie einen der oben genannten Schritte beendet haben, werden Sie keine laufenden Container mehr finden. In beiden Fällen cat
selbst beendet wurde, also hat Docker den Container beendet.
Jetzt für "-t", dies teilt dem Hauptprozess im Docker mit, dass seine Eingabe ein Endgerät ist.
Also
docker run -t alpine cat
gibt Ihnen eine leere Zeile, aber wenn Sie versuchen, "hello" einzugeben, erhalten Sie kein Echo. Dies liegt daran, dass währendcat
mit einem Terminaleingang verbunden ist, ist dieser Eingang nicht mit Ihrem Eingang verbunden. Das von Ihnen eingegebene "Hallo" hat die Eingabe voncat
nicht erreicht .cat
wartet auf Eingaben, die nie ankommen.echo "hello" | docker run -t alpine cat
gibt Ihnen auch eine leere Zeile und verlässt den Container nicht mit STRG-D, aber Sie erhalten kein Echo "Hallo", weil Sie-i
nicht bestanden haben
Wenn Sie STRG+C senden, erhalten Sie Ihre Shell zurück, aber wenn Sie docker ps
versuchen jetzt sehen Sie den cat
Container läuft noch. Das liegt daran, dass cat
wartet immer noch auf einen Eingabestrom, der nie geschlossen wurde. Ich habe keine sinnvolle Verwendung für -t
gefunden allein, ohne mit -i
kombiniert zu werden .
Nun zu -it
zusammen. Dies sagt cat, dass sein Eingang ein Terminal ist und verbindet gleichzeitig dieses Terminal mit dem Eingang von docker run
das ist ein Terminal. docker run/exec
stellt sicher, dass seine eigene Eingabe tatsächlich ein tty ist, bevor es an cat
übergeben wird . Aus diesem Grund erhalten Sie einen input device is not a TTY
wenn Sie echo "hello" | docker run -it alpine cat
versuchen weil in diesem Fall die Eingabe von docker run
selbst ist die Pipe vom vorherigen Echo und nicht das Terminal, wo docker run
ausgeführt wird
Warum sollten Sie schließlich -t
übergeben? wenn -i
wird den Trick machen, Ihre Eingabe mit cat
zu verbinden 's Eingabe? Dies liegt daran, dass Befehle die Eingabe anders behandeln, wenn es sich um ein Terminal handelt. Auch dies lässt sich am besten anhand eines Beispiels veranschaulichen
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
gibt Ihnen eine Passwortabfrage. Wenn Sie das Passwort eingeben, werden die Zeichen sichtbar gedruckt.docker run -i alpine sh
gibt Ihnen eine leere Zeile. Wenn Sie einen Befehl wiels
eingeben Sie erhalten eine Ausgabe, aber Sie erhalten keine Eingabeaufforderung oder farbige Ausgabe.
In den letzten beiden Fällen erhalten Sie dieses Verhalten, weil mysql
sowie shell
behandelten die Eingabe nicht als tty und verwendeten daher kein tty-spezifisches Verhalten wie das Maskieren der Eingabe oder das Einfärben der Ausgabe.
Lösung 2:
Diese Antwort hat mir geholfen, mich zurechtzufinden:
- standardmäßig (ohne weder
-i
noch-t
Optionen) sendet ein Docker-Container seine Ausgabe nur an STDOUT, - mit
-i
Option kommt Verbindung zu STDIN, -t
Option zieht einen Terminalschnittstellentreiber ein , das auf STDIN/STDOUT aufsetzt. Und wenn ein Terminaltreiber hereingezogen wird, muss die Kommunikation mit einem Container dem Terminalschnittstellenprotokoll entsprechen. Das Piping eines Strings nicht.
Lösung 3:
Ein tty zeigt an, dass Sie ein Terminal haben, etwas, das von xterm oder einer der vielen Linux-Befehlszeilenschnittstellen bereitgestellt wird. Es benötigt eine Tastatur und eine damit verbundene Textausgabeschnittstelle. Typische Gründe dafür sind die Unterstützung der Farbtextausgabe, die Handhabung verschiedener Tastenkombinationen (wie die Pfeiltasten) und die Möglichkeit, den Cursor auf dem Bildschirm zu bewegen.
Wenn Sie einen Befehl wie Ihren echo
in Docker leiten Beispiel zeigt, dass die Pipe die Eingabe ist und diese Pipe keine tty-Schnittstelle hat, sondern nur ein Textstrom ist. Der Versuch, damit ein tty zu erstellen, schlägt fehl, wie die Fehlermeldung anzeigt.