La -t
opción 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 es debido a que crea una separación entre la comprensión de lo que las capacidades del terminal se pueden utilizar sin necesidad de escribirlo en su programa directamente (leer páginas de manual en stty
, curses
).
Entonces, con eso como fondo, ejecute un contenedor sin opciones y, de forma predeterminada, tiene una secuencia estándar (así docker run | <cmd>
funciona); ejecuta con -i
, y obtienes flujo stdin agregado (así <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 es probablemente lo que desea. Básicamente hace que el inicio del contenedor parezca una sesión de conexión de terminal.
-it
banderas.docker run -i ubuntu
ydocker run -it ubuntu
verás la diferencia inmediatamente. "-i" le permite hacer que el contenedor espere la interacción del host, pero la interacción real desde la consola (terminal) es posible después de "asignar el controlador tty" con la marca "-t".-t
, pero no puedo modificar el comando de inicio de la ventana acoplable en producción. Así que necesito hacer que la aplicación piense que se inició-t
.Respuesta tardía, pero podría ayudar a alguien
docker run/exec -i
conectará el STDIN del comando dentro del contenedor al STDIN deldocker run/exec
mismo.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+ Dporque el proceso principalcat
está esperando la entrada del flujo infinito que es la entrada terminal deldocker run
.echo "hello" | docker run -i alpine cat
, imprimirá "hola" y saldrá inmediatamente porque secat
da cuenta de que la secuencia de entrada ha finalizado y termina por sí misma.Si intenta
docker ps
después de salir de cualquiera de los anteriores, no encontrará ningún contenedor en ejecución. En ambos casos, elcat
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 mientrascat
está conectado a una entrada de terminal, esta entrada no está conectada a su entrada. El "hola" que escribió no alcanzó la entrada decat
.cat
está esperando una entrada que nunca llega.echo "hello" | docker run -t alpine cat
también le dará una línea vacía y no saldrá del contenedor CTRL, Dpero no obtendrá un eco "hola" porque no pasó-i
Si envía CTRL+ C, recupera su shell, pero si lo intenta
docker ps
ahora, verá que elcat
contenedor sigue ejecutándose. Esto se debe acat
que todavía está esperando una secuencia de entrada que nunca se cerró. No he encontrado ningún uso útil para el-t
solo sin ser combinado 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 ladocker run
cual es una terminal.docker run/exec
se asegurará de que su propia entrada sea de hecho un tty antes de pasarlacat
. Es por eso que obtendrá uninput device is not a TTY
si lo intentaecho "hello" | docker run -it alpine cat
porque en este caso, la entrada dedocker run
sí mismo es la tubería del eco anterior y no el terminal dondedocker run
se ejecutaFinalmente, ¿por qué necesitaría pasar
-t
si-i
hará el truco de conectar su entrada acat
la entrada de? 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 -u root -p
le dará un mensaje 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 comols
se obtiene una salida, pero no obtendrá un mensaje o una salida de color.En los últimos dos casos, obtiene este comportamiento porque
mysql
, además deshell
no tratar la entrada como un tty, no utilizó el comportamiento específico de tty como enmascarar la entrada o colorear la salida.fuente
-t
y-i
qué opciones hacen!El
-t
argumento 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 acoplable 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:¡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
jwilder/nginx-proxy
contenedor acoplable de la siguiente manera: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
docker logs CONTAINER
donde seCONTAINER
encuentran los primeros dos caracteres de la ID de este contenedor. Esta ID DE CONTENEDOR se puede encontrar escribiendodocker ps -a
He visto este
-t
argumento mencionado brevemente en el siguiente enlace, donde dicehttps://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.
fuente
docker run --help
, nodocker -t --help
:-t, --tty=false Allocate a pseudo-TTY
"Lo que sé sobre esto
-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 era cuando quería restaurar una base de datos.
Normalmente lo hago
docker exec -ti mysql.5.7 mysql
: aquí ejecuto el comando mysql en el contenedor y obtengo un terminal interactivo.Agregué
<dump.sql
el comando anterior para poder restaurar un db. Pero falló concannot enable tty mode on non tty input
.Eliminando los
-t
ayudados. Aún no entiendo por qué:El último funciona. Espero que esto ayude a la gente.
fuente
-t
, pero no puedo modificar el comando de inicio de la ventana acoplable en producción. Así que necesito hacer que la aplicación piense que se inició-t
.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 toma en consideración la terminal dentro del contenedor de la ventana acoplable.
fuente
Cada proceso tiene tres flujos de datos, es decir
STDIN/ STDOUT/ STDERR
. Cuando un proceso se ejecuta en un contenedor, por defecto el terminal está conectado con la secuencia STDOUT del proceso que se ejecuta en el contenedor. Por lo tanto, todos los flujos de salida serán visibles mientras se ejecuta eldocker run
comando en la terminal. Pero si desea proporcionar información para el proceso en ejecución en el contenedor, entonces debe conectarse con el canal STDIN del proceso, que no es por defecto y se hace con eldocker run -i
comando.-t
se utiliza para operaciones de entrada interactivas / formateadas.fuente
El le
-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
Asignar un pseudo-TTYhttps://docs.docker.com/engine/reference/commandline/run/
fuente