La -topció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 -ifunciona); use -t, generalmente en la combinación -ity 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.
-itbanderas.docker run -i ubuntuydocker run -it ubuntuverá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 -iconectará el STDIN del comando dentro del contenedor al STDIN deldocker run/execmismo.Entonces
docker run -i alpine catle 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 principalcatestá 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 secatda cuenta de que la secuencia de entrada ha finalizado y termina por sí misma.Si intenta
docker psdespués de salir de cualquiera de los anteriores, no encontrará ningún contenedor en ejecución. En ambos casos, elcatmismo 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 catle dará una línea vacía, pero si intenta escribir "hola", no obtendrá ningún eco. Esto se debe a que mientrascatestá conectado a una entrada de terminal, esta entrada no está conectada a su entrada. El "hola" que escribió no alcanzó la entrada decat.catestá esperando una entrada que nunca llega.echo "hello" | docker run -t alpine cattambién le dará una línea vacía y no saldrá del contenedor CTRL, Dpero no obtendrá un eco "hola" porque no pasó-iSi envía CTRL+ C, recupera su shell, pero si lo intenta
docker psahora, verá que elcatcontenedor sigue ejecutándose. Esto se debe acatque todavía está esperando una secuencia de entrada que nunca se cerró. No he encontrado ningún uso útil para el-tsolo sin ser combinado con-i.Ahora, para
-itjuntos. Esto le dice a cat que su entrada es una terminal y al mismo tiempo conecte esta terminal a la entrada de ladocker runcual es una terminal.docker run/execse asegurará de que su propia entrada sea de hecho un tty antes de pasarlacat. Es por eso que obtendrá uninput device is not a TTYsi lo intentaecho "hello" | docker run -it alpine catporque en este caso, la entrada dedocker runsí mismo es la tubería del eco anterior y no el terminal dondedocker runse ejecutaFinalmente, ¿por qué necesitaría pasar
-tsi-ihará el truco de conectar su entrada acatla 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 -ple dará un mensaje de contraseña. Si escribe la contraseña, los caracteres se imprimen visiblemente.docker run -i alpine shte dará una línea vacía. Si escribe un comando comolsse 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 deshellno tratar la entrada como un tty, no utilizó el comportamiento específico de tty como enmascarar la entrada o colorear la salida.fuente
-ty-iqué opciones hacen!El
-targumento 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
dockeren 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 --helpif 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-proxycontenedor 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 CONTAINERdonde seCONTAINERencuentran los primeros dos caracteres de la ID de este contenedor. Esta ID DE CONTENEDOR se puede encontrar escribiendodocker ps -aHe visto este
-targumento 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
-tes 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.sqlel comando anterior para poder restaurar un db. Pero falló concannot enable tty mode on non tty input.Eliminando los
-tayudados. 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 runcomando 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 -icomando.-tse utiliza para operaciones de entrada interactivas / formateadas.fuente
El le
-itindica a Docker que asigne un pseudo-TTY conectado al stdin del contenedor, creando un shell bash interactivo en el contenedor.--interactive,-ifalseMantenga STDIN abierto incluso si no está conectado--tty,-tfalseAsignar un pseudo-TTYhttps://docs.docker.com/engine/reference/commandline/run/
fuente