Ich würde gerne wissen, wie man das folgende Verhalten ändert. Sagen wir, mein Terminal hat 28 Zeilen. Dann benutze ich die folgenden Befehle:
$ tput lines # my terminal
28
$ docker run --rm -it ubuntu:16.04 tput lines # docker container
24 ## WHY??
$ docker run --rm -it ubuntu:16.04 bash # docker container inside command
[email protected]:/# tput lines
28
Wie Sie sehen, auch wenn alle Ergebnisse 28 sein sollen, wenn ich den Container als docker run --rm -it ubuntu:16.04 tput lines
e anrufe, gibt es mir trotz der Größe meines Terminals immer 24. Dies ist nicht nur mit dem Ubuntu-Container, ich habe es auch mit debian (docker run --rm -it debian tput lines
) versucht und ich habe das gleiche Ergebnis 24.
Der Zweck besteht darin, das MDP-Präsentationswerkzeug zu verwenden, das die Leitungen in Ihrem Terminal berücksichtigt. Als meine Implementierung fehlgeschlagen ist, habe ich die Docker-Implementierung einer anderen Person ausprobiert, aber ich habe den gleichen Fehler erhalten.
Hier ist mein Fehler in einem Bild:
Hat jemand eine Idee, was es sein könnte und wie kann dies gelöst werden?
Update Sept. 2018: Überprüfen Sie, ob Docker 18.06 dasselbe Problem hat ( , das nicht auftreten sollte , nach moby/moby
, Ausgabe 33794 . ) und auch moby/moby
, Ausgabe 35407 und PR 37172 , Teil des 18.06 Versionshinweise ).
2016:
Das Ubuntu Dockerfile beinhaltet:
CMD ["/bin/bash"]
Das bedeutet, dass die Standardeinstellung ENTRYPOINT
sh -c
Ist (und ich bezweifle, dass tput line
In einer sh
Sitzung gut funktioniert, da tput verwendet die Datenbank terminfo
, die möglicherweise nur für Bash in diesem Bild festgelegt ist.)
Sie können versuchen, ENTRYPOINT
mit bash -c
Zu überschreiben und zu prüfen, ob dies besser funktioniert.
Das funktioniert jedoch nicht über die Befehlszeile:
docker run --entrypoint /bin/bash --rm -it ubuntu:16.04 -i -c 'tput lines'
24
Ich werde die Option zum Definieren eines benutzerdefinierten Bildes prüfen.
FROM ubuntu:16.04
ENTRYPOINT ["/bin/bash", "-c"]
Das Ergebnis ist jedoch dasselbe:
docker run --rm -it u 'tput lines'
24
Dies "funktioniert" jedoch:
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash" ]
Mit:
[email protected]:/c/Users/vonc/prog/testsu$ docker run --rm -it u -i -c 'ls; tput lines'
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
48
Möglicherweise liegt ein Synchronisierungsproblem vor, da derselbe Befehl von Zeit zu Zeit 24 zurückgibt.
Tatsächlich ergibt immer "nicht 24" mit:
FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ]
docker run --rm -it u -c 'sleep 0.1; ls; tput lines'
48
Das OP-Silgon schlägt in den Kommentaren vor:
docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"
In Anbetracht des Erfolgs des Schlafens besteht mein Verdacht darin, dass Docker den Container mit dem Befehl running dreht und der Client nach dem Start eine Verbindung zum laufenden Container herstellt. Normalerweise dauert dies Millisekunden.
Das brachte mich auf eine andere Idee:
[email protected]:/c/Users/vonc/prog/testsu$
docker run --entrypoint='/bin/bash' --name ub -d -it ubuntu:16.04
0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b
[email protected]:/c/Users/vonc/prog/testsu$
d attach ub
[email protected]:/# tput lines
48
[email protected]:/# exit
exit
[email protected]:/c/Users/vonc/prog/testsu$ drmae
0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b
Ein tput lines
Innerhalb einer angehängten Sitzung funktioniert einwandfrei.
(Siehe " So entfernen Sie alte und nicht verwendete Docker-Bilder " im Alias "drmae
")
thajeztah fügt in die Kommentare ein :
der Container wird erstellt und dann mit den Standardeinstellungen (
80x24
) gestartet. Danach (wenn-it
) wird eine Sitzung angehängt.
Die Sitzung gibt die Größe des Terminals an.
Siehe API " Ändern der Größe eines Containers TTY ".
DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee43a/resize?h=46&w=221
Weitere Informationen finden Sie unter docker issue 25450 .
Es bezieht sich auf Problem 10341 "Container erstellen oder starten sollte Höhe/Breite-Parameter akzeptieren" . Aleksa Sarai (Zypern) fügt hinzu ( Sept. 2016 ):
Dies ist in der Laufzeitspezifikation ( opencontainers/Laufzeitspezifikation PR 563 ) tatsächlich wieder aufgetaucht.
Da Windows die Möglichkeit erfordert, die Konsolengröße beim ersten Start festzulegen, wird sie möglicherweise für alle Plattformen hinzugefügt .
Das Silgon OP verweist auf den Code in api/client/container/run.go
:
// Telling the Windows daemon the initial size of the tty during start makes
// a far better user experience rather than relying on subsequent resizes
// to cause things to catch up.
if runtime.GOOS == "windows" {
hostConfig.ConsoleSize[0], hostConfig.ConsoleSize[1] = dockerCli.GetTtySize()
}
Mit der logischen Frage:
wäre es sinnvoll, diese Eigenschaft auch unter Linux zu verwenden und die anfängliche Konsolengröße mit diesem Wert festzulegen?
Kenfe-Mickaël Laventure (mlaventure
) ist darauf und ein neuer Patch könnte es zu Docker 1.13 schaffen ).
sie können jetzt goinside
Befehlszeilentool installieren mit:
Sudo npm install -g goinside
und gehen Sie in einen Docker-Container mit der richtigen Terminalgröße mit:
goinside docker_container_name
dank @VonC antwort wir haben eine lösung für dieses problem mit einem einfachen bash-schnipsel, das wir in ~/.profile
eingefügt haben:
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside
jetzt können Sie ohne Probleme mit der Terminalgröße in einen Docker-Container gelangen:
$ goinside containername
Denken Sie an source ~/.profile
, bevor Sie die goinside
-Funktion verwenden.
Wenn Sie die automatische Vervollständigung für goinside
aktivieren möchten, können Sie dieses Snippet in .profile
verwenden:
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export -f goinside;
wenn Sie zsh
als Standardterminal verwenden, können Sie dieses Snippet in Ihrer ~/.zshrc
-Datei verwenden:
autoload bashcompinit
bashcompinit
goinside(){
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
_goinside(){
COMPREPLY=( $(docker ps --format "{{.Names}}" -f name=$2) );
}
complete -F _goinside goinside;
export goinside;
Die Kommentare zu sh
versus terminfo sind weitgehend irrelevant. Der relevante Teil (in der gegebenen Antwort nicht klar) ist die Art und Weise, wie der Befehl ausgeführt wird. tput
überprüft drei Funktionen in der folgenden Reihenfolge (mit setupterm
):
TERM=xterm
, es ist 24 durch 80 ),LINES
und COLUMNS
.Ein Befehl, der ohne interaktive Shell ausgeführt wird könnte so ausgeführt werden, dass die aktuelle Fenstergröße nicht ermittelt wird. Dies ist beispielsweise eine Funktion von ssh
(das -t
Möglichkeit). Es wäre für Docker auch möglich (obwohl sinnlos), die Variablen LINES
und COLUMNS
zu setzen.
Jeder Fall (1) oder (3) reicht aus, um das Verhalten zu erklären; Zeitverzögerungen und Rennen einzuführen, tut das nicht.
Es wurde in Docker 18.06 behoben: https://github.com/moby/moby/issues/33794#issuecomment-406814439
Eine schöne Möglichkeit, bash im Container auszuführen, ohne auf Leitungsprobleme zu stoßen, ist hier :
docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti container bash
Ich habe gerade mit der Version Docker version 18.06.1-ce, build e68fc7a
getestet. Es scheint das gleiche Problem zu haben. Einer der Jungs in der github Ausgabe gab eine praktische Abhilfe :
docker run --rm -it -e COLUMNS=$COLUMNS -e LINES=$LINES -e TERM=$TERM -it ubuntu:16.04 tput lines