Error "El dispositivo de entrada no es un TTY"

427

Estoy ejecutando el siguiente comando desde mi Jenkinsfile. Sin embargo, aparece el error "El dispositivo de entrada no es un TTY" .

docker run -v $PWD:/foobar -it cloudfoundry/cflinuxfs2 /foobar/script.sh

¿Hay alguna manera de ejecutar el script desde el Jenkinsfilemodo interactivo?

Básicamente tengo un archivo llamado script.shque me gustaría ejecutar dentro del contenedor Docker.

Antonio
fuente
Para * nix, parece que no hay solución aquí. 'docker exec -i' no funciona, ni '-t'.
rjurney
1
@rjurney ¿Alguna vez encontró una solución para Docker Exec? He intentado -i y -t sin éxito. docker exec -it mycontainer bash certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch
@Hutch Lo siento, no puedo recordar :(
rjurney

Respuestas:

641

Elimine el -itde su cli para que no sea interactivo y elimine el TTY. Si tampoco lo necesita, por ejemplo, ejecutando su comando dentro de un script de Jenkins o cron, debe hacer esto.

O puede cambiarlo a -isi ha ingresado una entrada al comando del acoplador que no proviene de un TTY. Si tiene algo como xyz | docker ...o docker ... <inputen su línea de comando, haga esto.

O puede cambiarlo a -tsi desea soporte TTY pero no lo tiene disponible en el dispositivo de entrada. Haga esto para formatear el color de la salida en sus registros, o para cuando luego lo conecte al contenedor con un terminal adecuado.

O si necesita un terminal interactivo y no se está ejecutando en un terminal en Linux o MacOS, use una interfaz de línea de comando diferente. Se informa que PowerShell incluye este soporte en Windows.


¿Qué es un TTY? Es una interfaz de terminal que admite salida de color, secuencias de escape, mover el cursor, etc., que proviene de los viejos tiempos de terminales tontos conectados a mainframes. Hoy lo proporcionan los terminales de comando de Linux y las interfaces ssh. Vea el artículo de Wikipedia para más detalles .

BMitch
fuente
10
Estoy usando este comando junto con mysql -psin especificar una contraseña. Cuando solo agrega -ila solicitud de contraseña, nunca aparece. Con solo agregar, -taparece el mensaje, pero parece no leer la entrada (que se imprime literalmente en lugar de estar oculto por el mensaje) en absoluto, ni siquiera cuando se presiona volver; solo ctrl-c puede terminarlo. ¿De alguna manera es posible usar el cliente mysql con docker de esa manera?
ohcibi
95

Para aquellos que luchan con este error y git bash en Windows, solo usen PowerShell donde -itfunciona perfectamente.

Piotr Justyna
fuente
12
Esto no responde la pregunta. La pregunta es sobre Docker en Jenkins, no sobre git bash en Windows.
45
Bien. cierto, y nunca fue su intención. La pregunta aparece en Google cuando busca este mensaje de error específico. Pensé, mejor tener la respuesta en algún lado que no tenerla en absoluto. Claramente, algunas personas lo encontraron útil :)
Piotr Justyna
3
El problema con Powershell como TTY para las operaciones de shell es que no pasa correctamente las teclas de flecha, como la flecha hacia arriba para el ciclo del historial de comandos. Funciona muy bien aparte de esa deficiencia.
Corgalore
2
Si desea continuar usando Git Bash, vea esta respuesta en otra pregunta o la respuesta winpty a continuación
tessafyi
68

No es exactamente lo que estás preguntando, pero:

¡La tecla -T ayudaría a las personas que usan docker-compose exec!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup
yestema
fuente
2
Exactamente lo que estaba buscando. ¿Sabes por qué funciona esto?
Ulad Kasach
66
Justo lo que necesitaba también. Según la ayuda: -T Desactiva la asignación de pseudo-tty. Por defecto docker-compose exec asigna un TTY.
TS
Gracias hombre. Lo busco por docker-compose!
ADyDyka
¡Esto funcionó para mí!
rlorenzo
59

Si está (como yo) usando git bash en windows, solo necesita poner

winpty

antes de su 'línea acoplable':

winpty docker exec -it some_cassandra bash
Gremi64
fuente
¿Cómo descargar winpty?
Mor Shemesh
66
¿Lo intentaste antes de preguntar? Creo que viene con Git (el mío está dentro ... / Git / usr / bin)
Gremi64
Tienes razón, está bajoC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh
31

Creo que debe estar en un TTY para que Docker pueda asignar un TTY (la -topción). Jenkins ejecuta sus trabajos no en un TTY.

Dicho esto, el script que está ejecutando dentro de Jenkins también puede querer ejecutarlo localmente. En ese caso, puede ser realmente conveniente tener un TTY asignado para que pueda enviar señales como ctrl+ ccuando se ejecuta localmente.

Para solucionar esto, haga que su secuencia de comandos utilice opcionalmente la -topción, así:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...
Gareth A. Lloyd
fuente
Este error me sucede cuando ejecuto un docker run…comando desde una tarea de archivo desencadenada por un gancho de git
Édouard Lopez
1
Esta debería ser la respuesta aceptada. en realidad aborda el problema de manera universalmente aplicable
roothahn
11

cuando se usa 'git bash',

1) ejecuto el comando:

docker exec -it 726fe4999627 /bin/bash

Tengo el error:

the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

2) luego, ejecuto el comando:

winpty docker exec -it 726fe4999627 /bin/bash

Tengo otro error:

OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"D:/Git/usr/bin/
bash.exe\": stat D:/Git/usr/bin/bash.exe: no such file or directory": unknown

3) tercero, ejecuto el:

winpty docker exec -it 726fe4999627 bash

funcionó.

cuando uso 'powershell', todo funcionó bien.

wangsir
fuente
También me golpeé la cabeza contra la pared durante un par de horas con estos problemas usando bash. ¡Cambió a Powershell y todo funciona ahora!
David Spenard el
5

si usa Windows, intente con cmd, para mí funciona. compruebe si se inicia la ventana acoplable.

Diego Santa Cruz Mendezú
fuente
1

winpty funciona siempre que no especifique volúmenes para montar como ".: / mountpoint" o "$ {pwd}: / mountpoint"

La mejor solución que he encontrado es usar el complemento git-bash dentro de Visual Code Studio y usar el terminal para iniciar y detener contenedores o componer acopladores.

Oxidado1
fuente
1

Sé que esto no está respondiendo directamente la pregunta en cuestión, sino para cualquiera que se encuentre con esta pregunta y esté usando WSL ejecutando Docker para Windows y Cmder o Conemu.

El truco no es usar Docker, que está instalado en Windows en / mnt / c / Program Files / Docker / Docker / resources / bin / docker.exe, sino instalar ubuntu / linux Docker. Vale la pena señalar que no puede ejecutar Docker en sí mismo desde WSL, pero puede conectarse a Docker para Windows desde el cliente Linux Docker.

Instalar Docker en Linux

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce

Conéctese a Docker para Windows en el puerto 2375 que debe habilitarse desde la configuración de Docker para Windows.

docker -H localhost:2375 run -it -v /mnt/c/code:/var/app -w "/var/app" centos:7

O configure la variable docker_host que le permitirá omitir el modificador -H

export DOCKER_HOST=tcp://localhost:2375

Ahora debería poder conectarse interactivamente con una sesión de terminal tty.

Damo
fuente
0

Mi paso de canalización Jenkins que se muestra a continuación falló con el mismo error.

       steps {
            echo 'Building ...' 
            sh 'sh ./Tools/build.sh'
        }

En mi archivo de comandos " build.sh ", el comando " docker run " genera este error cuando fue ejecutado por el trabajo de Jenkins. Sin embargo, estaba funcionando bien cuando el script se ejecutó en el terminal de shell. El error ocurrió debido a que la opción -t pasó al comando docker run que, como sé, intenta asignar el terminal y falla si no hay un terminal para asignar.

En mi caso, he cambiado el script para pasar la opción -t solo si se pudo detectar un terminal. Aquí está el código después de los cambios:

DOCKER_RUN_OPTIONS="-i --rm"

# Only allocate tty if we detect one
if [ -t 0 ] && [ -t 1 ]; then
    DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -t"
fi

docker run $DOCKER_RUN_OPTIONS --name my-container-name  my-image-tag
Namik Hajiyev
fuente