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

17

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 repariert".

Ich weiß , dass docker run‚s -tOption für‚Vergeben Sie einen Pseudo-TTY‘steht, und ich habe gelesen historischen Überblick über was TTY steht für , aber es half nicht , mir zu verstehen , was für einen Vertrag hier verletzt wird.

Mikhail Vasin
quelle
Es ist nicht redundant, Docker kann ein TTY erstellen, ohne dass etwas daran angehängt wird. Ihre Ausgabe würde Zeichen für Farbe usw. enthalten, aber Ihre Terminalausgabe würde nicht in die Eingabe des Containers geleitet. Die eingegebenen Zeichen werden für den nächsten Befehl in die Warteschlange gestellt, den Sie nach dem Beenden des Docker-Befehls ausführen.
BMitch
Kann ich tty im Docker starten? Ich habe eine App, die nicht mehr funktioniert, mit der ich den Docker nicht ausführen -tkann, aber ich kann den Docker-Startbefehl in der Produktion nicht ändern. Daher muss ich der App den Eindruck vermitteln, dass sie damit gestartet wurde -t.
mvorisek

Antworten:

8

Diese Antwort hat mir geholfen, den Kopf herumzureißen:

  • Standardmäßig (ohne Weder -inoch -tOptionen) sendet ein Docker-Container seine Ausgabe nur an STDOUT.
  • mit -iOption kommt Verbindung zu STDIN,
  • -tDie Option ruft einen Terminal-Schnittstellentreiber auf, der auf STDIN / STDOUT aufbaut. Und wenn ein Terminal-Treiber eingezogen wird, muss die Kommunikation mit einem Container dem Terminal-Schnittstellenprotokoll entsprechen . Piping eine Zeichenfolge nicht.
Mikhail Vasin
quelle
7

Späte Antwort, könnte aber jemandem helfen

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

So

  • docker run -i alpine catgibt Ihnen eine leere Zeile für die Eingabe. Tippe "hallo", du bekommst ein Echo "hallo". Der Container wird erst beendet, wenn Sie STRG + D senden, da der Hauptprozess catauf die Eingabe aus dem unendlichen Stream wartet, der die Terminaleingabe von ist docker run.
  • Auf der anderen Seite echo "hello" | docker -i run alpine catwird "Hallo" gedruckt und sofort beendet, da catfestgestellt wird, dass der Eingabestream beendet wurde und sich selbst beendet.

Wenn Sie docker psnach dem Beenden einer der oben genannten Aktionen versuchen , werden Sie keine laufenden Container finden. In beiden Fällen hat sich catselbst beendet, daher hat Docker den Container beendet.

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

So

  • docker run -t alpine catwird Ihnen eine leere Zeile geben, aber wenn Sie versuchen "Hallo" einzugeben, werden Sie kein Echo bekommen. Dies liegt daran cat, dass dieser Eingang nicht mit Ihrem Eingang verbunden ist, solange er an einen Klemmeneingang angeschlossen ist. Das von Ihnen eingegebene "Hallo" hat die Eingabe von nicht erreicht cat. catwartet auf eine Eingabe, die niemals eintrifft.
  • echo "hello" | docker run -t alpine cat gibt Ihnen auch eine leere Zeile und beendet 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 docker psjetzt versuchen , sehen Sie, dass der catContainer noch ausgeführt wird. Dies liegt daran, dass catimmer noch auf einen Eingabestream gewartet wird, der nie geschlossen wurde. Ich habe keinen nützlichen Gebrauch für das -talleine gefunden, ohne mit kombiniert zu werden -i.

Nun zu -itzweit. Dies teilt cat mit, dass sein Eingang ein Terminal ist und verbindet gleichzeitig dieses Terminal mit dessen Eingang docker runein Terminal ist. docker run/execwird sicherstellen, dass seine eigene Eingabe tatsächlich ein Tty ist, bevor sie an übergeben wird cat. Aus diesem Grund erhalten Sie ein, input device is not a TTYwenn Sie es versuchen, echo "hello" | docker run -it alpine catda in diesem Fall die Eingabe von docker runsich aus die Pipe des vorherigen Echos und nicht das Terminal docker runist, auf dem ausgeführt wird

Schließlich, warum sollten Sie überholen müssen, -twenn -iSie Ihren Eingang mit catdem Eingang verbinden wollen? Dies liegt daran, dass Befehle die Eingabe unterschiedlich 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 -pSie erhalten eine Passwortabfrage. Wenn Sie das Kennwort eingeben, werden die Zeichen sichtbar gedruckt.
  • docker run -i alpine shwird Ihnen eine leere Zeile geben. Wenn Sie einen Befehl wie lsfolgt eingeben, erhalten Sie eine Ausgabe, jedoch keine Eingabeaufforderung oder farbige Ausgabe.

In den letzten beiden Fällen Sie dieses Verhalten, weil mysqlauch shellnicht der Eingang als tty Behandlung und somit nicht tty spezifisches Verhalten wie die Eingangs Maskierung oder die Ausgabe verwendet haben Färbung.

Ahmed Ghonim
quelle
4

Ein tty gibt an, dass Sie über ein Terminal verfügen, das von xterm oder einer der vielen Linux-Befehlszeilenschnittstellen bereitgestellt wird. Es benötigt eine Tastatur und eine dazugehörige 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 in docker leiten, wie in Ihrem echoBeispiel gezeigt, ist diese Pipe die Eingabe und diese Pipe hat keine tty-Schnittstelle, sondern nur einen Textstrom. Der Versuch, ein Tty mit diesem zu erstellen, schlägt fehl, wie in der Fehlermeldung angegeben.

BMitch
quelle
Es gibt für mich immer noch eine Lücke zwischen "einer Tastatur und einer Ausgabeschnittstelle" und "STDIN / STDOUT". Offensichtlich können Sie das Konzept "Cursorposition" nicht auf STDOUT anwenden, da STDOUT ein Stream und kein Bildschirm ist. Welche Spezifikationen beschreiben die Abstraktion der Ausgabeschnittstelle, die über STDOUT steht (ich denke, das ist sie)?
Mikhail Vasin
1
Es ist eine Schnittstelle, die auf stdin / stdout läuft. en.wikipedia.org/wiki/POSIX_terminal_interface
BMitch