web-dev-qa-db-fra.com

Confus au sujet de l'option -t de Docker pour allouer un pseudo-ATS

Qu'est-ce que cette option fait exactement? J'ai beaucoup lu sur ATS et je suis encore confus. J'ai joué avec ne pas avoir le -t et juste -i et il semble que les programmes qui attendent une entrée d'utilisateur jettent une erreur sans le -t. Pourquoi est-il important d'activer le pseudo-ATS?

167
user1099123

L'option "-t" indique comment Unix/Linux gère l'accès au terminal. Dans le passé, un terminal était une connexion fixe, plus tard une connexion basée sur un modem. Ceux-ci avaient des pilotes de périphériques physiques (c'étaient de véritables équipements). Une fois les réseaux généralisés entrés en service, un pilote de pseudo-terminal a été développé. En effet, cela crée une séparation entre le fait de comprendre quelles capacités de terminal peuvent être utilisées sans avoir à l'écrire directement dans votre programme (lisez les pages de manuel sur stty, curses).

Donc, avec cela en arrière-plan, lancez un conteneur sans options et par défaut vous avez un flux stdout (donc docker run | <cmd> fonctionne); lancer avec "-i", et vous obtenez le flux stdin ajouté (donc <cmd> | docker run -i fonctionne); utilisez "-t", généralement dans la combinaison "-it" et vous ajoutez un pilote de terminal qui, si vous interagissez avec le processus, est probablement ce que vous voulez. Fondamentalement, le démarrage du conteneur ressemble à une session de connexion de terminal.

148
Twweeed

Selon une recherche sur Google, l'argument "-t" n'est PAS bien documenté ni souvent mentionné par de nombreuses personnes.

Il ne s'affiche même pas lorsque vous affichez une liste (ce qui devrait être) de tous les arguments du client docker en tapant "docker" à l'invite Bash (avec la dernière version de 1.8.1).

En fait, si vous essayez d'obtenir une aide spécifique à propos de cet argument en tapant "docker -t --help" si donne cette réponse étonnamment vague:

"indicateur fourni mais non défini: -t"

Donc, vous ne pouvez pas être blâmé pour avoir été dérouté à propos de cet argument!

Il existe une mention dans la documentation en ligne de Docker qui dit que c'est pour "Allouer un pseudo-tty" et qui est souvent utilisée avec -i:

https://docs.docker.com/reference/run/

Je l'ai utilisé dans la documentation du formidable conteneur jwilder/nginx-proxy docker de la manière suivante:

docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx

Dans ce cas, il envoie la sortie au terminal virtuel (invite/terminal Bash) dans ce conteneur de menu fixe. Vous pouvez ensuite voir cette sortie en exécutant la commande docker "docker logs CONTAINER", où CONTAINER est le premier couple de caractères de l'ID de ce conteneur. Cet identifiant de conteneur peut être trouvé en tapant "docker ps -a"

J'ai vu cet argument "-t" mentionné brièvement dans le lien suivant, où il est écrit: "Les indicateurs -t et -i allouent un pseudo-tty et maintiennent stdin ouvert même s'ils ne sont pas attachés. Cela vous permettra d'utiliser le contenant comme un VM traditionnel tant que l'invite bash est en cours d'exécution. "

https://coreos.com/os/docs/latest/getting-started-with-docker.html

J'espère que ça aide! Je ne sais pas pourquoi cela n'est pas documenté ou utilisé beaucoup. Peut-être que c'est expérimental et sera implémenté comme une fonctionnalité documentée dans les versions à venir.

67
Rich

Réponse tardive, mais pourrait aider quelqu'un

docker run/exec -i connectera le STDIN de la commande à l'intérieur du conteneur au STDIN du docker run/exec lui-même.

Alors

  • docker run -i Alpine cat vous donne une ligne vide en attente de saisie. Tapez "bonjour" vous obtenez un écho "bonjour". Le conteneur ne se fermera pas avant l'envoi de CTRL + D car le processus principal cat attend une entrée du flux infini qui constitue l'entrée de terminal du docker run.
  • Par contre, echo "hello" | docker -i run Alpine cat affichera "hello" et se fermera immédiatement car cat remarquera que le flux d'entrée est terminé et se termine.

Si vous essayez docker ps après avoir quitté l'une des options ci-dessus, vous ne trouverez aucun conteneur en cours d'exécution. Dans les deux cas, cat elle-même s'est terminée, ainsi Docker a mis fin au conteneur.

Maintenant pour "-t", cela indique au processus principal à l'intérieur du menu fixe que son entrée est un terminal.

Alors

  • docker run -t Alpine cat vous donnera une ligne vide, mais si vous essayez de taper "bonjour", vous n'obtiendrez aucun écho. En effet, bien que cat soit connecté à une entrée de terminal, cette entrée n'est pas connectée à votre entrée. Le "bonjour" que vous avez tapé n'a pas atteint l'entrée de cat. cat attend une entrée qui n'arrive jamais.
  • echo "hello" | docker run -t Alpine cat vous donnera également une ligne vide et ne quittera pas le conteneur sur CTRL-D mais vous n'obtiendrez pas d'écho "hello" car vous n'avez pas réussi à passer -i

Si vous envoyez CTRL + C, vous récupérez votre shell, mais si vous essayez maintenant docker ps, vous voyez que le conteneur cat est toujours en cours d'exécution. En effet, cat attend toujours un flux d'entrée qui n'a jamais été fermé. Je n'ai trouvé aucune utilité pour le -t seul sans être combiné à -i.

Maintenant, pour -it ensemble. Ceci indique à cat que son entrée est un terminal et connecte en même temps ce terminal à l'entrée de docker run qui est un terminal. docker run/exec s'assurera que sa propre entrée est en fait un terminal avant de le transmettre à cat. C'est pourquoi vous obtiendrez un input device is not a TTY si vous essayez echo "hello" | docker run -it Alpine cat car dans ce cas, l'entrée de docker run est elle-même le canal de l'écho précédent et non le terminal où docker run est exécuté

Enfin, pourquoi devriez-vous passer -t si -i fera le tour de connecter votre entrée à l'entrée de cat? En effet, les commandes traitent l’entrée différemment s’il s’agit d’un terminal. Ceci est également mieux illustré par l'exemple

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p vous donnera un mot de passe Invite. Si vous tapez le mot de passe, les caractères sont imprimés de manière visible.
  • docker run -i Alpine sh vous donnera une ligne vide. Si vous tapez une commande comme ls, vous obtenez une sortie, mais vous n'obtiendrez pas d'invite ni de sortie colorée.

Dans les deux derniers cas, vous obtenez ce comportement parce que mysql ainsi que Shell ne traitaient pas l'entrée comme un terminal et n'utilisaient donc pas le comportement spécifique au terminal comme le masquage de l'entrée ou la coloration de la sortie.

28
Ahmed Ghonim

Ce que je sais sur le -t est le suivant:

docker exec -ti CONTAINER bash - me permet de "me connecter" dans le conteneur. Cela ressemble à du ssh-ing (ce n'est pas).

Mais le problème était lorsque je voulais restaurer une base de données.

Habituellement, je faisdocker exec -ti mysql.5.7 mysql - Ici, j'exécute la commande mysql dans le conteneur et obtiens un terminal interactif.

J'ai ajouté <dump.sql à la commande précédente pour pouvoir restaurer une base de données. Mais cela a échoué avec cannot enable tty mode on non tty input.

Retrait du -t aidé. Je ne comprends toujours pas pourquoi:

docker exec -i mysql.5.7 mysql < dump.sql

Le dernier fonctionne. J'espère que cela aide les gens.

5
mist