Späte Antwort, könnte aber jemandem helfen
docker run/exec -i verbindet die Standardeingabe des Befehls im Container mit der Standardeingabe des docker run/exec selbst.
So
-
docker run -i alpine cat gibt Ihnen eine leere Zeile, die auf Eingabe wartet. Geben Sie "hello" ein und Sie erhalten ein Echo "hello". Der Container wird erst beendet, wenn Sie STRG + D senden, da der Hauptprozess cat wartet auf Eingaben aus dem unendlichen Stream, der der Terminaleingang des docker run.
- Auf der anderen Seite
echo "hello" | docker run -i alpine cat wird "hallo" drucken und sofort beenden, weil cat stellt fest, dass der Eingabestream beendet wurde und sich selbst beendet.
Wenn du es versuchst docker ps nachdem Sie einen der oben genannten Schritte beendet haben, werden Sie keine laufenden Container finden. In beiden Fällen, cat selbst beendet wurde, hat Docker den Container beendet.
Jetzt für "-t" teilt dies dem Hauptprozess im Docker mit, dass seine Eingabe ein Terminalgerät ist.
So
-
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ährend cat an einen Terminaleingang angeschlossen ist, ist dieser Eingang nicht mit Ihrem Eingang verbunden. Das von Ihnen eingegebene "hallo" hat die Eingabe von nicht erreicht cat. 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 nicht bestanden haben -i
Wenn Sie STRG + C senden, erhalten Sie Ihre Shell zurück, aber wenn Sie es versuchen docker ps jetzt sehen Sie die cat container läuft noch. Dies liegt daran, dass cat wartet immer noch auf einen Eingabestream, der nie geschlossen wurde. Ich habe keine nützliche Verwendung für die gefunden -t allein, ohne mit kombiniert zu werden -i.
Jetzt, für -it zusammen. Dies teilt cat mit, dass sein Eingang ein Terminal ist, und verbindet dieses Terminal gleichzeitig mit dem Eingang von docker run welches ist ein Terminal. docker run/exec wird sicherstellen, dass seine eigene Eingabe tatsächlich ein tty ist, bevor es an übergeben wird cat. Deshalb erhalten Sie eine input device is not a TTY wenn du es versuchst echo "hello" | docker run -it alpine cat weil in diesem Fall die Eingabe von docker run selbst ist die Pipe vom vorherigen Echo und nicht das Terminal, wo docker run wird ausgeführt
Schließlich, warum solltest du bestehen müssen -t wenn -i wird den Trick machen, Ihre Eingabe mit zu verbinden cat's Eingabe? Dies liegt daran, dass Befehle die Eingabe anders behandeln, wenn es sich um ein Terminal handelt. Dies lässt sich auch am besten anhand eines Beispiels veranschaulichen
-
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p wird Ihnen eine Passwortabfrage geben. Wenn Sie das Passwort eingeben, werden die Zeichen sichtbar gedruckt.
-
docker run -i alpine sh wird Ihnen eine leere Zeile geben. Wenn Sie einen Befehl wie eingeben ls sie erhalten eine Ausgabe, aber 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 Maskieren der Eingabe oder Einfärben der Ausgabe.