what pseudo compose allocate docker tty pty

compose - Confundido acerca de la opción Docker-t para asignar un pseudo-TTY



docker compose tty (6)

¿Qué hace exactamente esta opción? He estado leyendo mucho en TTY y todavía estoy confundido. Jugué con no tener el -t y solo -i y parece que los programas que esperan la entrada del usuario arrojan un error sin el -t . ¿Por qué es importante habilitar pseudo-TTY?


El -it indica a Docker que asigne un pseudo-TTY conectado al stdin del contenedor, creando un shell bash interactivo en el contenedor.

--interactive , -i false Mantenga STDIN abierto incluso si no está conectado

--tty , -t false --tty un pseudo-TTY

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


El argumento -t NO está bien documentado, o muchas personas lo mencionan a menudo, según una búsqueda en Google.

Ni siquiera aparece cuando muestra una lista de (lo que debería ser) todos los argumentos del cliente de docker escribiendo docker en el indicador Bash (con la última versión de 1.8.1).

De hecho, si intenta obtener ayuda específica sobre este argumento escribiendo docker -t --help if da esta respuesta increíblemente vaga:

Indicador proporcionado pero no definido: -t

¡Entonces, no se te puede culpar por estar confundido sobre este argumento!

Hay una mención en la documentación en línea de Docker que dice que es "Asignar un pseudo-tty" y a menudo se usa con -i :

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

Vi que se usaba en la documentación del excelente contenedor acoplable jwilder/nginx-proxy de la siguiente manera:

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

En este caso, lo que hace es enviar la salida al tty ''virtual'' (símbolo del sistema Bash / terminal) dentro de este contenedor acoplable. Luego puede ver esta salida ejecutando el comando docker logs CONTAINER donde CONTAINER es el primer par de caracteres de la ID de este contenedor. Este ID DE CONTENEDOR se puede encontrar escribiendo docker ps -a

He visto este argumento -t mencionado brevemente en el siguiente enlace, donde dice

Los indicadores -t y -i asignan un pseudo-tty y mantienen abierto el stdin incluso si no está adjunto. Esto le permitirá usar el contenedor como una VM tradicional siempre que se ejecute el indicador bash.

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

¡Espero que esto ayude! No estoy seguro de por qué esto no está documentado o se usa mucho. Tal vez sea experimental y se implementará como una característica documentada en las próximas versiones.


En Linux cuando ejecuta un comando, necesita un terminal (tty) para ejecutarlo.

Entonces, cuando desee conectarse a la ventana acoplable (o ejecutar el comando en el contenedor de la ventana acoplable), debe proporcionar la opción -t que tiene en cuenta la terminal dentro del contenedor de la ventana acoplable.


La opción -t va a cómo Unix / Linux maneja el acceso a la terminal. En el pasado, un terminal era una conexión de línea dura, luego una conexión basada en módem. Estos tenían controladores de dispositivos físicos (eran piezas reales de equipo). Una vez que las redes generalizadas entraron en uso, se desarrolló un controlador de pseudo-terminal. Esto se debe a que crea una separación entre comprender qué capacidades de terminal se pueden usar sin la necesidad de escribirlo directamente en su programa (lea las páginas de stty en stty , curses ).

Entonces, con eso como fondo, ejecute un contenedor sin opciones y, de forma predeterminada, tiene una secuencia stdout (por lo que docker run | <cmd> funciona); ejecute con -i , y obtendrá la secuencia stdin agregada (entonces <cmd> | docker run -i funciona); use -t , generalmente en la combinación -it y tiene un controlador de terminal agregado, que si está interactuando con el proceso, probablemente sea lo que desea. Básicamente, hace que el inicio del contenedor parezca una sesión de conexión de terminal.


Lo que sé sobre -t es lo siguiente:

docker exec -ti CONTAINER bash - me permite "iniciar sesión" en el contenedor. Se siente como una mierda (no lo es).

Pero el problema fue cuando quise restaurar una base de datos.

Usualmente hago docker exec -ti mysql.5.7 mysql - Aquí ejecuto el comando mysql en el contenedor y obtengo un terminal interactivo.

<dump.sql al comando anterior para poder restaurar un db. Pero falló con cannot enable tty mode on non tty input .

Eliminar el -t ayudó. Aún no entiendo por qué:

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

El último funciona. Espero que esto ayude a la gente.


Respuesta tardía, pero podría ayudar a alguien

docker run/exec -i conectará el STDIN del comando dentro del contenedor al STDIN del mismo docker run/exec .

Entonces

  • docker run -i alpine cat le da una línea vacía en espera de entrada. Escriba "hola" obtendrá un eco "hola". El contenedor no saldrá hasta que envíe CTRL + D porque el proceso principal cat está esperando la entrada del flujo infinito que es la entrada del terminal de la docker run .
  • Por otro lado echo "hello" | docker -i run alpine cat echo "hello" | docker -i run alpine cat imprimirá "hola" y saldrá inmediatamente porque cat da cuenta de que la secuencia de entrada ha finalizado y termina por sí misma.

Si prueba docker ps después de salir de cualquiera de los anteriores, no encontrará ningún contenedor en ejecución. En ambos casos, el cat mismo ha terminado, por lo tanto, la ventana acoplable ha terminado el contenedor.

Ahora para "-t", esto le dice al proceso principal dentro de Docker que su entrada es un dispositivo terminal.

Entonces

  • docker run -t alpine cat le dará una línea vacía, pero si intenta escribir "hola", no obtendrá ningún eco. Esto se debe a que mientras cat está conectado a una entrada de terminal, esta entrada no está conectada a su entrada. El "hola" que escribió no alcanzó la entrada de cat . cat está esperando una entrada que nunca llega.
  • echo "hello" | docker run -t alpine cat echo "hello" | docker run -t alpine cat también le dará una línea vacía y no saldrá del contenedor en CTRL - D pero no obtendrá un eco "hola" porque no pasó -i

Si envía CTRL + C , recupera su shell, pero si prueba docker ps ahora, verá que el contenedor cat todavía se está ejecutando. Esto se debe a que cat todavía está esperando una secuencia de entrada que nunca se cerró. No he encontrado ningún uso útil para -t solo sin combinarlo con -i .

Ahora, para -it juntos. Esto le dice a cat que su entrada es una terminal y al mismo tiempo conecte esta terminal a la entrada de docker run que es una terminal. docker run/exec se asegurará de que su propia entrada sea de hecho un tty antes de pasarla a cat . Es por eso que obtendrá un input device is not a TTY si intenta echo "hello" | docker run -it alpine cat echo "hello" | docker run -it alpine cat porque en este caso, la entrada de docker run es la tubería del eco anterior y no el terminal donde se docker run

Finalmente, ¿por qué necesitaría pasar -t si -i hará el truco de conectar su entrada a la entrada de cat ? Esto se debe a que los comandos tratan la entrada de manera diferente si es una terminal. Esto también se ilustra mejor con un ejemplo.

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p le dará una solicitud de contraseña. Si escribe la contraseña, los caracteres se imprimen visiblemente.
  • docker run -i alpine sh te dará una línea vacía. Si escribe un comando como ls obtendrá un resultado, pero no obtendrá un mensaje o un resultado en color.

En los últimos dos casos, obtienes este comportamiento porque mysql y shell no trataban la entrada como tty y, por lo tanto, no usaban un comportamiento específico de tty como enmascarar la entrada o colorear la salida.