Die -t
Option zeigt an, wie Unix / Linux den Terminalzugriff behandelt. In der Vergangenheit war ein Terminal eine Hardline-Verbindung, später eine modembasierte Verbindung. Diese hatten physische Gerätetreiber (sie waren echte Ausrüstungsgegenstände). Nach der Verwendung verallgemeinerter Netzwerke wurde ein Pseudo-Terminal-Treiber entwickelt. Dies liegt daran, dass eine Trennung zwischen dem Verständnis, welche Terminalfunktionen verwendet werden können, entsteht, ohne dass diese direkt in Ihr Programm geschrieben werden müssen (siehe Manpages auf stty
, curses
).
Führen Sie vor diesem Hintergrund einen Container ohne Optionen aus, und standardmäßig haben Sie einen Standard-Stream ( docker run | <cmd>
funktioniert also). Wenn Sie mit ausführen -i
, wird der <cmd> | docker run -i
Standard- Stream hinzugefügt ( funktioniert also). Verwenden Sie diese Option -t
normalerweise in der Kombination, -it
und Sie haben einen Terminaltreiber hinzugefügt. Wenn Sie mit dem Prozess interagieren, ist dies wahrscheinlich das, was Sie möchten. Grundsätzlich sieht der Container-Start wie eine Terminalverbindungssitzung aus.
-it
Flags.docker run -i ubuntu
unddocker run -it ubuntu
Sie werden den Unterschied sofort sehen. Mit "-i" können Sie den Container so einstellen, dass er auf die Interaktion vom Host wartet. Die tatsächliche Interaktion von der Konsole (Terminal) ist jedoch möglich, nachdem Sie den tty-Treiber mit dem Flag "-t" "zugewiesen" haben.-t
, aber ich kann den Docker-Startbefehl in der Produktion nicht ändern. Also muss ich die App denken lassen, dass sie gestartet wurde-t
.Späte Antwort, könnte aber jemandem helfen
docker run/exec -i
verbindet die STDIN des Befehls im Container mit der STDIN desdocker run/exec
selbst.So
docker run -i alpine cat
gibt Ihnen eine leere Zeile, die auf Eingabe wartet. Geben Sie "Hallo" ein, Sie erhalten ein Echo "Hallo". Der Container wird erst beendet, wenn Sie CTRL+ senden, Dda der Hauptprozesscat
auf die Eingabe aus dem unendlichen Stream wartet, der die Terminaleingabe des istdocker run
.echo "hello" | docker run -i alpine cat
wird "Hallo" gedruckt und sofort beendet, dacat
bemerkt wird, dass der Eingabestream beendet wurde und sich selbst beendet.Wenn Sie versuchen,
docker ps
nachdem Sie einen der oben genannten Schritte beendet haben, werden Sie keine laufenden Container finden. In beiden Fällen hat sichcat
selbst beendet, so dass Docker den Container beendet hat.Für "-t" teilt dies dem Hauptprozess im Docker mit, dass seine Eingabe ein Endgerät ist.
So
docker run -t alpine cat
gibt Ihnen eine leere Zeile, aber wenn Sie versuchen, "Hallo" einzugeben, erhalten Sie kein Echo. Dies liegt darancat
, dass dieser Eingang zwar mit einem Klemmeneingang verbunden ist, jedoch nicht mit Ihrem Eingang. Das "Hallo", das Sie eingegeben haben, hat die Eingabe von nicht erreichtcat
.cat
wartet auf Eingaben, die nie eintreffen.echo "hello" | docker run -t alpine cat
gibt Ihnen auch eine leere Zeile und verlässt den Container nicht weiter CTRL- Daber Sie erhalten kein Echo "Hallo", weil Sie nicht bestanden haben-i
Wenn Sie CTRL+ senden C, erhalten Sie Ihre Shell zurück. Wenn Sie es
docker ps
jetzt versuchen , wird dercat
Container weiterhin ausgeführt. Dies liegt daran, dasscat
immer noch auf einen Eingabestream gewartet wird, der nie geschlossen wurde. Ich habe keine nützliche Verwendung für mich-t
allein gefunden, ohne mit kombiniert zu werden-i
.Nun zu
-it
zusammen. 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 eine,input device is not a TTY
wenn Sie es versuchen,echo "hello" | docker run -it alpine cat
da in diesem Fall die Eingabe von sichdocker run
selbst die Pipe des vorherigen Echos ist und nicht das Terminal, an dem siedocker run
ausgeführt wirdSchließlich, warum sollten Sie bestehen müssen,
-t
wenn-i
Sie den Trick tun, Ihre Eingabe mitcat
der Eingabe 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 veranschaulichendocker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -p
gibt Ihnen eine Passwortabfrage. Wenn Sie das Passwort eingeben, werden die Zeichen sichtbar gedruckt.docker run -i alpine sh
gibt Ihnen eine leere Zeile. Wenn Sie einen Befehlls
eingeben, wie Sie eine Ausgabe erhalten, erhalten Sie 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
-t
und welche-i
Optionen es gibt!-t
Laut einer Google-Suche ist das Argument NICHT gut dokumentiert oder wird von vielen Menschen häufig erwähnt.Es wird nicht einmal angezeigt, wenn Sie eine Liste aller Docker-Client-Argumente anzeigen (was sollte das sein), indem Sie
docker
an der Bash-Eingabeaufforderung (mit der neuesten Version von 1.8.1) eingeben .In der Tat, wenn Sie versuchen, spezifische Hilfe zu diesem Argument zu erhalten, indem Sie tippen,
docker -t --help
wenn dies diese erstaunlich vage Antwort gibt:Sie können also nicht dafür verantwortlich gemacht werden, dass Sie über dieses Argument verwirrt sind!
In der Docker-Online-Dokumentation wird erwähnt, dass "Pseudo-tty zuweisen" verwendet wird und häufig verwendet wird mit
-i
:https://docs.docker.com/reference/run/
Ich habe gesehen, dass es in der Dokumentation für den großartigen
jwilder/nginx-proxy
Docker-Container folgendermaßen verwendet wurde:In diesem Fall wird die Ausgabe an die 'virtuelle' tty (Bash-Eingabeaufforderung / Terminal) in diesem Docker-Container gesendet. Anschließend können Sie diese Ausgabe sehen , indem Sie den Docker Befehl ausgeführt wird,
docker logs CONTAINER
woCONTAINER
das erste Paar der Zeichen dieses Behälters ID ist. Diese CONTAINER-ID kann durch Eingabe ermittelt werdendocker ps -a
Ich habe dieses
-t
Argument kurz im folgenden Link erwähnt gesehen, wo es stehthttps://coreos.com/os/docs/latest/getting-started-with-docker.html
Ich hoffe das hilft! Ich bin mir nicht sicher, warum dies nicht viel dokumentiert oder verwendet wird. Vielleicht ist es experimentell und wird in kommenden Versionen als dokumentierte Funktion implementiert.
quelle
docker run --help
, nichtdocker -t --help
:-t, --tty=false Allocate a pseudo-TTY
"Was ich über die weiß
-t
ist Folgendes:docker exec -ti CONTAINER bash
- erlaubt mir, mich im Container "einzuloggen". Es fühlt sich an wie ssh-ing (es ist nicht).Das Problem war jedoch, als ich eine Datenbank wiederherstellen wollte.
Normalerweise tue ich das
docker exec -ti mysql.5.7 mysql
- Hier führe ich den Befehl mysql im Container aus und erhalte ein interaktives Terminal.Ich habe
<dump.sql
zum vorherigen Befehl hinzugefügt , damit ich eine Datenbank wiederherstellen kann. Aber es ist gescheitert mitcannot enable tty mode on non tty input
.Entfernen der
-t
geholfenen. Ich verstehe immer noch nicht warum:Der letzte funktioniert. Hoffe das hilft den Menschen.
quelle
-t
, aber ich kann den Docker-Startbefehl in der Produktion nicht ändern. Also muss ich die App denken lassen, dass sie gestartet wurde-t
.Wenn Sie unter Linux einen Befehl ausführen, benötigen Sie ein Terminal (tty), um ihn auszuführen.
Wenn Sie also eine Verbindung zum Docker herstellen möchten (oder einen Befehl im Docker-Container ausführen möchten), müssen Sie die Option -t angeben, die die Berücksichtigung des Terminals im Docker-Container berücksichtigt.
quelle
Jeder Prozess hat drei Datenströme, dh
STDIN/ STDOUT/ STDERR
. Wenn ein Prozess in einem Container ausgeführt wird, ist das Terminal standardmäßig mit dem STDOUT-Stream des im Container ausgeführten Prozesses verbunden. Daher sind alle Ausgabestreams sichtbar, während derdocker run
Befehl im Terminal ausgeführt wird. Wenn Sie jedoch Eingaben für den laufenden Prozess im Container bereitstellen möchten, müssen Sie eine Verbindung mit dem STDIN-Kanal des Prozesses herstellen, der nicht standardmäßig ist und mit demdocker run -i
Befehl ausgeführt wird.-t
wird für interaktive / formatierte Eingabevorgänge verwendet.quelle
Der
-it
Docker wird angewiesen, ein Pseudo-TTY zuzuweisen, das mit dem Standard des Containers verbunden ist, und eine interaktive Bash-Shell im Container zu erstellen.--interactive
,-i
false
Halten Sie STDIN offen, auch wenn es nicht angeschlossen ist--tty
,-t
false
Ordnen Sie eine Pseudo-TTY zuhttps://docs.docker.com/engine/reference/commandline/run/
quelle