it-swarm.com.de

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

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 nur "entferne -t und es wird behoben".

Ich weiß das docker run 's -t Option steht für "Allocate a Pseudo-TTY" und ich habe historische Übersichten darüber gelesen, wofür TTY steht , aber es hat mir nicht geholfen verstehen, welche Art von Vertrag hier verletzt wird.

19
Mikhail Vasin

Diese Antwort hat mir geholfen, meinen Kopf herumzuwickeln:

  • standardmäßig (ohne -i Noch -t Optionen) Ein Docker-Container sendet seine Ausgabe nur an STDOUT.
  • mit -i Option kommt Verbindung zu STDIN,
  • -t Option ruft einen Terminal-Interface-Treiber auf, der über STDIN/STDOUT funktioniert. Und wenn ein Terminaltreiber eingezogen wird, muss die Kommunikation mit einem Container dem Terminalschnittstellenprotokoll entsprechen. Das Piping einer Zeichenfolge funktioniert nicht.
8
Mikhail Vasin

Späte Antwort, könnte aber jemandem helfen

docker run/exec -i Verbindet die STDIN des Befehls im Container mit der STDIN des docker run/exec Selbst.

Damit

  • docker run -i Alpine cat Gibt Ihnen eine leere Zeile, die auf die Eingabe wartet. Geben Sie "Hallo" ein, Sie erhalten ein Echo "Hallo". Der Container wird erst beendet, wenn Sie STRG + D senden, da der Hauptprozess cat auf die Eingabe aus dem unendlichen Stream wartet, der die Terminal-Eingabe von docker run Ist.
  • Andererseits gibt echo "hello" | docker -i run Alpine cat "Hallo" aus und wird sofort beendet, da cat feststellt, dass der Eingabestream beendet wurde und sich selbst beendet.

Wenn Sie docker ps Versuchen, nachdem Sie einen der oben genannten Schritte beendet haben, werden keine laufenden Container gefunden. In beiden Fällen wurde cat selbst beendet, sodass Docker den Container beendet hat.

Für "-t" teilt dies dem Hauptprozess im Docker mit, dass seine Eingabe ein Endgerät ist.

Damit

  • docker run -t Alpine cat Gibt eine leere Zeile aus, aber wenn Sie versuchen, "Hallo" einzugeben, erhalten Sie kein Echo. Dies liegt daran, dass cat zwar mit einem Terminal-Eingang verbunden ist, dieser Eingang jedoch nicht mit Ihrem Eingang verbunden ist. Das von Ihnen eingegebene "Hallo" hat die Eingabe von cat nicht erreicht. cat wartet auf Eingaben, die niemals eintreffen.
  • echo "hello" | docker run -t Alpine cat Gibt Ihnen auch eine leere Zeile und verlässt den Container nicht bei 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. Wenn Sie jetzt docker ps Versuchen, wird der Container cat weiterhin ausgeführt. Dies liegt daran, dass cat immer noch auf einen Eingabestream wartet, der nie geschlossen wurde. Ich habe keine nützliche Verwendung für -t Allein gefunden, ohne mit -i Kombiniert zu werden.

Nun zu -it Zusammen. Dies teilt cat mit, dass sein Eingang ein Terminal ist, und verbindet dieses Terminal gleichzeitig mit dem Eingang von docker run, Bei dem es sich um ein Terminal handelt. docker run/exec Stellt sicher, dass die eigene Eingabe tatsächlich ein tty ist, bevor sie 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, da in diesem Fall die Eingabe von docker run Selbst die Pipe des vorherigen Echos ist und nicht das Terminal, an dem docker run Wird ausgeführt

Warum sollten Sie schließlich -t Übergeben müssen, wenn -i Den Trick ausführt, Ihre Eingabe mit der Eingabe von cat zu verbinden? 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 Gibt Ihnen eine Passwort-Eingabeaufforderung. Wenn Sie das Passwort eingeben, werden die Zeichen sichtbar gedruckt.
  • docker run -i Alpine sh Gibt eine leere Zeile aus. Wenn Sie einen Befehl wie ls eingeben, erhalten Sie eine Ausgabe, aber keine Eingabeaufforderung oder farbige Ausgabe.

In den letzten beiden Fällen tritt dieses Verhalten auf, weil mysql sowie Shell die Eingabe nicht als tty behandelten und daher kein tty-spezifisches Verhalten wie das Maskieren der Eingabe oder das Färben der Ausgabe verwendeten .

9
Ahmed Ghonim

Ein tty zeigt an, dass Sie ein Terminal haben, das von xterm oder einer der vielen Linux-Befehlszeilenschnittstellen bereitgestellt wird. Es benötigt eine Tastatur und eine 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 über den Bildschirm zu bewegen.

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

4
BMitch