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 -t
Option 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.
-t
kann, 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
.Antworten:
Diese Antwort hat mir geholfen, den Kopf herumzureißen:
-i
noch-t
Optionen) sendet ein Docker-Container seine Ausgabe nur an STDOUT.-i
Option kommt Verbindung zu STDIN,-t
Die 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.quelle
Späte Antwort, könnte aber jemandem helfen
docker run/exec -i
verbindet die STDIN des Befehls im Container mit der STDIN des Befehlsdocker run/exec
.So
docker run -i alpine cat
gibt 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 Hauptprozesscat
auf die Eingabe aus dem unendlichen Stream wartet, der die Terminaleingabe von istdocker run
.echo "hello" | docker -i run alpine cat
wird "Hallo" gedruckt und sofort beendet, dacat
festgestellt wird, dass der Eingabestream beendet wurde und sich selbst beendet.Wenn Sie
docker ps
nach dem Beenden einer der oben genannten Aktionen versuchen , werden Sie keine laufenden Container finden. In beiden Fällen hat sichcat
selbst 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 cat
wird Ihnen eine leere Zeile geben, aber wenn Sie versuchen "Hallo" einzugeben, werden Sie kein Echo bekommen. Dies liegt darancat
, 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 erreichtcat
.cat
wartet 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 ps
jetzt versuchen , sehen Sie, dass dercat
Container noch ausgeführt wird. Dies liegt daran, dasscat
immer noch auf einen Eingabestream gewartet wird, der nie geschlossen wurde. Ich habe keinen nützlichen Gebrauch für das-t
alleine gefunden, ohne mit kombiniert zu werden-i
.Nun zu
-it
zweit. Dies teilt cat mit, dass sein Eingang ein Terminal ist und verbindet gleichzeitig dieses Terminal mit dessen Eingangdocker run
ein Terminal ist.docker run/exec
wird sicherstellen, dass seine eigene Eingabe tatsächlich ein Tty ist, bevor sie an übergeben wirdcat
. Aus diesem Grund erhalten Sie ein,input device is not a TTY
wenn Sie es versuchen,echo "hello" | docker run -it alpine cat
da in diesem Fall die Eingabe vondocker run
sich aus die Pipe des vorherigen Echos und nicht das Terminaldocker run
ist, auf dem ausgeführt wirdSchließlich, warum sollten Sie überholen müssen,
-t
wenn-i
Sie Ihren Eingang mitcat
dem 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 veranschaulichendocker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
Sie erhalten eine Passwortabfrage. Wenn Sie das Kennwort eingeben, werden die Zeichen sichtbar gedruckt.docker run -i alpine sh
wird Ihnen eine leere Zeile geben. Wenn Sie einen Befehl wiels
folgt eingeben, erhalten Sie eine Ausgabe, jedoch keine Eingabeaufforderung oder farbige Ausgabe.In den letzten beiden Fällen Sie dieses Verhalten, weil
mysql
auchshell
nicht der Eingang als tty Behandlung und somit nicht tty spezifisches Verhalten wie die Eingangs Maskierung oder die Ausgabe verwendet haben Färbung.quelle
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
echo
Beispiel 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.quelle