41 votes

Menu fixe le nombre de lignes dans le terminal de changer à l'intérieur de docker

Je voudrais savoir comment faire pour modifier le comportement suivant. Disons que mon terminal a 28 lignes. Puis-je utiliser les commandes suivantes:

$ 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
root@810effa2777c:/# tput lines
28

Comme vous pouvez le voir, même lorsque tous les résultats doivent être 28, lorsque je vais appeler le conteneur docker run --rm -it ubuntu:16.04 tput lines il me donne toujours des 24 malgré la taille de mon terminal. Ce n'est pas seulement avec la ubuntu conteneur, j'ai aussi essayé avec debian (docker run --rm -it debian tput lines) et je vais avoir le même résultat 24.

Le but de cela est d'utiliser le mdp outil de présentation qui prend en compte les lignes de votre terminal. Lors de ma mise en échec, j'ai essayé une autre personne du panneau de mise en œuvre , mais j'ai couru à la même erreur.

Voici mon erreur dans une image:

Docker number of lines in terminal changing inside docker

Est-ce quelqu'un a une idée de ce que cela pourrait être et comment cela peut-il être résolu?

45voto

Soorena Points 1167

Mise à JOUR

vous pouvez maintenant installer goinside outil en ligne de commande:

sudo npm install -g goinside

et aller à l'intérieur d'un conteneur docker avec une bonne taille du terminal avec:

goinside docker_container_name

La logique derrière goinside

merci à @VonC réponse , nous avons une solution pour ce problème avec un bash simple extrait de ce que nous avons mis en ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

maintenant, vous êtes en mesure d'obtenir à l'intérieur d'un conteneur docker sans terminal de la taille des problèmes avec:

$ goinside containername


rappelez-vous d' source ~/.profile avant d'utiliser l' goinside fonction.


activation de l'auto-complétion de bash

(comme elle est partagée dans l'un des commentaires ci-dessous) si vous souhaitez activer l'auto-complétion pour goinside vous pouvez utiliser cet extrait en .profile:

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;

activation de l'auto-complétion de zsh

si vous utilisez zsh que votre terminal par défaut, vous pouvez utiliser ce morceau de code à l'intérieur de votre ~/.zshrc le fichier:

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;

18voto

VonC Points 414372

Mise À Jour Sept. 2018: vérifiez si le panneau 18.06 a le même problème (il ne devrait pas, après l' moby/moby question 33794, et aussi moby/moby question 35407 et PR 37172, une partie de la 18.06 notes de version).


2016:

L' Ubuntu Dockerfile comprend:

CMD ["/bin/bash"]

Cela signifie que la valeur par défaut ENTRYPOINT est sh -c (et je doute qu' tput line fonctionne bien dans un sh session, depuis tput utilise terminfo de la base de données, qui peut être défini que pour le bash de cette image)

Vous pouvez essayer de remplacer ENTRYPOINT avec bash -c et de vérifier si cela fonctionne mieux.

Qui ne fonctionne pas à partir de la ligne de commande si:

docker run --entrypoint /bin/bash --rm  -it ubuntu:16.04 -i -c 'tput lines'
24

Je vais vérifier la possibilité de définir une image personnalisée.

FROM ubuntu:16.04
ENTRYPOINT ["/bin/bash", "-c"]

Le résultat est le même:

docker run --rm  -it u 'tput lines'
24

Toutefois, cela "fonctionne":

FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash" ]

Avec:

docker@default:/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

Il y a peut être un problème de synchronisation, que la même commande ne retour 24, de temps à autre.

En fait, la suivant toujours le retour "n'24" avec:

FROM ubuntu:16.04
ENTRYPOINT [ "/bin/bash", "-l", "-i", "-c" ]

docker run --rm  -it u -c 'sleep 0.1; ls; tput lines'
48

L' OP silgon propose dans les commentaires:

docker run --rm -it --entrypoint /bin/bash ubuntu:16.04 -c "sleep 0.1 && tput lines"

Comme BMitch les commentaires ci-dessous:

Étant donné le succès de sommeil de mes soupçons, c'est que le panneau de tours le récipient avec la commande en cours, et une fois en haut, le client s'attache à l'exécution de conteneur. Généralement quelque chose qui ne prend que quelques millisecondes.

Cela m'a donné une autre idée:

docker@default:/c/Users/vonc/prog/testsu$ 
docker run --entrypoint='/bin/bash' --name ub -d -it ubuntu:16.04
  0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b
docker@default:/c/Users/vonc/prog/testsu$ 
d attach ub
  root@0d9b8783afbb:/# tput lines
  48
  root@0d9b8783afbb:/# exit
exit
docker@default:/c/Users/vonc/prog/testsu$ drmae
0d9b8783afbb5e3ff4232da071d3f357985351ea1ce4d142bf6617ac456fb76b

Un tput lines dans une joint session fonctionne très bien.
(Sur l' drmae alias, voir "Comment enlever les anciens et inutilisés Docker images")


thajeztah ajoute dans les commentaires:

le conteneur est créé, puis a commencé avec les valeurs par défaut (80x24), et par la suite (lors de l' -it), une session est attaché.
La session est de spécifier la taille de la borne;

Voir "Redimensionner un conteneur ATS" de l'API.

 DEBU[0244] Calling POST /v1.25/containers/c42fd5c4eb79c06fd7f9912b8359022f7d93887afbb33b57a67ed8bb7bfee4‌​3a/resize?h=46&w=221 

Pour en savoir plus, voir le panneau question 25450.
Elle est liée à la question 10341 "Conteneur de créer ou de démarrer devrait accepter hauteur/largeur params". Aleksa Saraï (cyphar) ajoute (Sept. 2016):

Ce qui a fait sauté de nouveau à l'intérieur de l'exécution-spec (opencontainers/runtime-spec PR 563).
En gros, depuis Windows requiert la capacité à définir la console de taille au premier démarrage, nous pourrions mettre fin à l'ajouter à toutes les plates-formes.


L' OP silgon points pour le code en 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()
}

Avec la question logique:

serait-il judicieux d'utiliser cette propriété sur Linux en tant que bien, et la console de la taille à l'aide de cette valeur?

Kenfe-Mickaël Laventure (mlaventure) qui est sur elle, et un nouveau patch pourrait-il faire de Docker 1.13.

1voto

Nico Toub Points 679

Il a été résolu dans le panneau 18.06: https://github.com/moby/moby/issues/33794#issuecomment-406814439

1voto

Thomas Dickey Points 29672

Les commentaires à propos de sh versus terminfo sont largement hors de propos. La partie pertinente (pas clair dans la réponse donnée) est la façon dont la commande est exécutée. tput vérifie les trois fonctions dans l'ordre suivant (à l'aide d' setupterm):

  1. la taille du terminal à partir de la base de données terminfo (de nombreuses descriptions de ne pas donner cette information, mais avec TERM=xterm, il est de 24 par 80),
  2. le nombre réel de lignes, si elle peut obtenir ces informations à partir du système d'exploitation (c'est à dire, la taille de la fenêtre courante), et
  3. l' LINES et COLUMNS variables d'environnement.

Une commande qui est exécutée sans un shell interactif peut être exécuté d'une manière qui s'oppose à l'obtention de la taille de la fenêtre courante. Par exemple, ce qui est une caractéristique de l' ssh (le -t option). Aussi, il serait possible (bien qu'inutile) pour Docker pour définir l' LINES et COLUMNS variables.

Les deux cas (1) ou (3) est suffisant pour expliquer le comportement; l'introduction de délais et de courses de ne pas le faire.

1voto

silgon Points 2646

Je viens de tester avec la version Docker version 18.06.1-ce, build e68fc7a. Il semble avoir le même problème. Cependant, l'un des gars dans le github question a donné une pratique solution de contournement:

docker run --rm -it -e COLUMNS=$COLUMNS -e LINES=$LINES -e TERM=$TERM -it ubuntu:16.04 tput lines

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X