Was genau bedeutet „das Eingabegerät ist kein TTY“ in der „Docker Run“-Ausgabe?

Was genau bedeutet „das Eingabegerät ist kein TTY“ in der „Docker Run“-Ausgabe?

Dies ist ein Befehl, der funktioniert:

$ echo 'hi there' | docker run -i ubuntu cat
hi there

Dies ist ein Befehl, der mit einer Fehlermeldung antwortet:

$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY

Ich möchte genau herausfinden, was hier passiert. Nicht einfach „remove -t und es wird behoben“.

Ich weiß, dass docker rundie -tOption für "Allocate a pseudo-TTY" steht, und ich habe gelesenhistorische Übersichten darüber, wofür TTY steht, aber es hat mir nicht geholfen zu verstehen, gegen welche Art von Vertrag hier verstoßen wird.

Antwort1

Späte Antwort, könnte aber jemandem helfen

docker run/exec -iverbindet die STDIN des Befehls im Container mit der STDIN docker run/execselbst.

Also

  • docker run -i alpine catgibt Ihnen eine leere Zeile, die auf eine Eingabe wartet. Geben Sie „hallo“ ein, Sie erhalten ein Echo „hallo“. Der Container wird erst beendet, wenn Sie STRG+D senden, da der Hauptprozess catauf eine Eingabe aus dem unendlichen Stream wartet, der die Terminaleingabe des ist docker run.
  • Andererseits echo "hello" | docker run -i alpine catwird „Hallo“ gedruckt und das Programm wird sofort beendet, weil cates erkennt, dass der Eingabestrom zu Ende ist, und sich selbst beendet.

Wenn Sie es docker psnach dem Beenden eines der oben genannten Programme versuchen, werden Sie keine laufenden Container finden. In beiden Fällen catwurde Docker selbst beendet, sodass Docker den Container beendet hat.

Nun zu „-t“: Dies teilt dem Hauptprozess im Docker mit, dass seine Eingabe ein Terminalgerät ist.

Also

  • docker run -t alpine catgibt Ihnen eine leere Zeile, aber wenn Sie versuchen, „hallo“ einzugeben, erhalten Sie kein Echo. Das liegt daran, dass zwar catmit einem Terminaleingang verbunden ist, dieser Eingang jedoch nicht mit Ihrem Eingang verbunden ist. Das von Ihnen eingegebene „hallo“ hat den Eingang von nicht erreicht cat. catwartet auf einen Eingang, der nie eintrifft.
  • echo "hello" | docker run -t alpine catgibt Ihnen auch eine leere Zeile und verlässt den Container nicht mit STRG-D, aber Sie erhalten kein Echo "Hallo", weil Sie nicht übergeben haben-i

Wenn Sie STRG+C senden, erhalten Sie Ihre Shell zurück, aber wenn Sie es docker psjetzt versuchen, sehen Sie, dass der catContainer immer noch läuft. Das liegt daran, catdass immer noch auf einen Eingabestream wartet, der nie geschlossen wurde. Ich habe keine sinnvolle Verwendung für -talleiniges Verwenden von gefunden, ohne es mit zu kombinieren -i.

Nun zu -itzusammen. Dies teilt cat mit, dass sein Eingang ein Terminal ist und verbindet gleichzeitig dieses Terminal mit dem Eingang von , docker runder ein Terminal ist. docker run/execstellt sicher, dass sein eigener Eingang tatsächlich ein tty ist, bevor es an weitergegeben wird cat. Deshalb erhalten Sie ein , input device is not a TTYwenn Sie versuchen echo "hello" | docker run -it alpine cat, weil in diesem Fall der Eingang von docker runsich selbst die Pipe vom vorherigen Echo ist und nicht das Terminal, auf dem docker runausgeführt wird

Und schließlich: Warum müssen Sie -t„if -iwill“ übergeben, um Ihre Eingabe mit der Eingabe von zu verbinden cat? 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 -pwird Ihnen eine Passwortabfrage angezeigt. Wenn Sie das Passwort eingeben, werden die Zeichen sichtbar gedruckt.
  • docker run -i alpine shgibt eine leere Zeile aus. Wenn Sie einen Befehl wie lsdiesen eingeben, erhalten Sie eine Ausgabe, aber keine Eingabeaufforderung oder farbige Ausgabe.

In den letzten beiden Fällen tritt dieses Verhalten auf, weil wir die Eingabe mysqlnicht shellals TTY behandelt haben und daher kein TTY-spezifisches Verhalten wie das Maskieren der Eingabe oder das Einfärben der Ausgabe verwendet haben.

Antwort2

Diese Antworthat mir geholfen, das zu verstehen:

  • Standardmäßig (ohne die Optionen „weder -inoch“ -t) sendet ein Docker-Container seine Ausgabe nur an STDOUT.
  • mit -iOption kommt Anschluss an STDIN,
  • -tOption zieht einen Terminalschnittstellentreiber ein, das auf STDIN/STDOUT basiert. Und wenn ein Terminaltreiber eingebunden wird, muss die Kommunikation mit einem Container denTerminal-Schnittstellenprotokoll. Das Weiterleiten einer Zeichenfolge funktioniert nicht.

Antwort3

Ein tty zeigt an, dass Sie ein Terminal haben, das von xterm oder einer der vielen Linux-Befehlszeilenschnittstellen bereitgestellt wird. Es muss eine Tastatur und eine zugehörige Textausgabeschnittstelle haben. Typische Gründe dafür sind die Unterstützung der Farbtextausgabe, die Handhabung verschiedener Tastenkombinationen (wie der Pfeiltasten) und die Möglichkeit, den Cursor über den Bildschirm zu bewegen.

Wenn Sie einen Befehl wie in Ihrem Beispiel gezeigt in Docker weiterleiten echo, ist diese Pipe die Eingabe und diese Pipe hat keine TTY-Schnittstelle, sondern nur einen Textstrom. Der Versuch, damit ein TTY zu erstellen, schlägt fehl, wie die Fehlermeldung angibt.

verwandte Informationen