Errore "Il dispositivo di input non è un TTY"


426

Sto eseguendo il seguente comando dal mio Jenkinsfile. Tuttavia, viene visualizzato l'errore "Il dispositivo di input non è un TTY" .

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

C'è un modo per eseguire lo script dalla Jenkinsfilemodalità interattiva senza fare?

Fondamentalmente ho un file chiamato script.shche vorrei eseguire all'interno del contenitore Docker.


Per * nix, sembra che non ci sia soluzione qui. 'docker exec -i' non funziona, né '-t'.
rjurney,

1
@rjurney Hai mai trovato una soluzione per il docker exec? Avrei provato -i e -t senza successo. docker exec -it mycontainer bash certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch

@Hutch Spiacente, non ricordo :(
rjurney il

Risposte:


640

Rimuovi il -it dal tuo cli per renderlo non interattivo e rimuovere il TTY. Se non ne hai bisogno, ad esempio eseguendo il comando all'interno di uno script Jenkins o cron, dovresti farlo.

Oppure puoi cambiarlo in -ise hai inserito un input nel comando docker che non proviene da un TTY. Se hai qualcosa di simile xyz | docker ...o docker ... <inputnella tua riga di comando, fallo.

Oppure puoi cambiarlo in -tse desideri il supporto TTY ma non lo hai disponibile sul dispositivo di input. Fallo per la formattazione del colore dell'output nei tuoi registri o per quando in seguito ti colleghi al contenitore con un terminale appropriato.

Oppure, se hai bisogno di un terminale interattivo e non sei in esecuzione in un terminale su Linux o MacOS, usa un'interfaccia a riga di comando diversa. Si dice che PowerShell includa questo supporto su Windows.


Che cos'è un TTY? È un'interfaccia terminale che supporta output a colori, sequenze di escape, spostamento del cursore, ecc., Che proviene dai vecchi tempi dei terminali stupidi collegati ai mainframe. Oggi è fornito dai terminali di comando di Linux e dalle interfacce ssh. Vedi l' articolo di Wikipedia per maggiori dettagli .


10
Sto usando questo comando insieme mysql -psenza specificare una password. Quando si aggiunge solo -ila richiesta della password non viene mai visualizzata. Con solo l'aggiunta -tdel prompt appare ma sembra non leggere l'input (che viene stampato letteralmente invece di essere nascosto dal prompt), nemmeno quando si preme return; solo ctrl-c può terminarlo. È in qualche modo possibile utilizzare il client mysql con docker in questo modo?
ohcibi,

95

Per coloro che lottano con questo errore e si basano su Windows, basta usare PowerShell dove -itfunziona perfettamente.


12
Questo non risponde alla domanda. La domanda riguarda la finestra mobile in Jenkins, non git bash su Windows.

45
Bene. vero, e non è mai stato previsto. La domanda viene visualizzata in google quando si cerca questo messaggio di errore specifico. Ho pensato, meglio avere la risposta da qualche parte piuttosto che non averla affatto. Chiaramente alcune persone lo hanno trovato utile :)
Piotr Justyna,

3
Il problema con Powershell come TTY per le operazioni della shell è che non passa correttamente i tasti freccia, come la freccia su per la cronologia dei comandi di ciclismo. Funziona benissimo oltre a questo difetto.
Corgalore,

2
Se vuoi continuare a usare Git Bash, vedi questa risposta su un'altra domanda o la risposta winpty di seguito
tessafyi

68

Non è esattamente quello che stai chiedendo, ma:

Il tasto -T aiuterebbe le persone che usano exec docker-compose!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup

2
esattamente quello che stavo cercando. sai perché funziona?
Ulad Kasach,

6
Proprio quello di cui avevo bisogno. Secondo l'aiuto: -T Disabilita l'allocazione pseudo-tty. Per impostazione predefinita docker-compose exec alloca un TTY.
TS

Grazie uomo. Lo cerco per docker-compose!
ADyDyka

Questo ha funzionato per me!
rolenzo

59

Se stai (come me) usi git bash su Windows, devi solo metterlo

winpty

prima della tua 'docker line':

winpty docker exec -it some_cassandra bash

come si scarica winpty?
Mor Shemesh,

6
Hai provato prima di chiedere? Penso che arrivi con Git (il mio è dentro ... / Git / usr / bin)
Gremi64,

Hai ragione, è sottoC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh il

31

Credo che devi essere in un TTY affinché la finestra mobile sia in grado di allocare un TTY (l' -topzione). Jenkins esegue i suoi lavori non in un TTY.

Detto questo, lo script che stai eseguendo all'interno di Jenkins potresti anche voler eseguire localmente. In tal caso può essere davvero conveniente avere un TTY allocato in modo da poter inviare segnali come ctrl+ cquando lo si esegue localmente.

Per risolvere questo problema, fai in modo che lo script usi l' -topzione, in questo modo:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...

Questo errore si verifica quando eseguo il docker run…comando da un'attività makefile attivata da un hook git
Édouard Lopez,

1
questa dovrebbe essere la risposta accettata. in realtà risolve il problema in modo universalmente applicabile
roothahn

11

quando si usa 'git bash',

1) Eseguo il comando:

docker exec -it 726fe4999627 /bin/bash

Ho l'errore:

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

2) quindi, eseguo il comando:

winpty docker exec -it 726fe4999627 /bin/bash

Ho un altro errore:

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) terzo, eseguo il:

winpty docker exec -it 726fe4999627 bash

ha funzionato.

quando utilizzo "PowerShell", tutto ha funzionato bene.


Ho anche sbattuto la testa contro il muro per un paio d'ore con questi problemi usando bash. Passato a Powershell e tutto funziona ora!
David Spenard,


1

winpty funziona fintanto che non si specificano volumi da montare come ".: / mountpoint" o "$ {pwd}: / mountpoint"

La soluzione migliore che ho trovato è utilizzare il plug-in git-bash in Visual Code Studio e utilizzare il terminale per avviare e arrestare i contenitori o comporre docker.


1

So che questo non sta rispondendo direttamente alla domanda attuale, ma per chiunque si ponga questa domanda che sta utilizzando WSL con Docker per Windows e cmder o conemu.

Il trucco non è usare Docker che è installato su Windows in / mnt / c / Programmi / Docker / Docker / resources / bin / docker.exe ma piuttosto installare Docker ubuntu / linux. Vale la pena sottolineare che non è possibile eseguire Docker stesso da WSL ma è possibile connettersi a Docker per Windows dal client Docker di Linux.

Installa Docker su 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

Connettersi a Docker per windows sulla porta 2375 che deve essere abilitato dalle impostazioni nella docker per windows.

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

Oppure imposta la variabile docker_host che ti permetterà di omettere l'opzione -H

export DOCKER_HOST=tcp://localhost:2375

Ora dovresti essere in grado di connetterti in modo interattivo con una sessione terminale tty.


0

Il passaggio della pipeline Jenkins mostrato di seguito non è riuscito con lo stesso errore.

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

Nel mio file di script " build.sh " il comando " Esegui finestra mobile " genera questo errore quando è stato eseguito dal lavoro Jenkins. Tuttavia funzionava bene quando lo script veniva eseguito nel terminale della shell. L'errore si è verificato a causa dell'opzione -t passata al comando di esecuzione docker che, come so, tenta di allocare il terminale e fallisce se non c'è un terminale da allocare.

Nel mio caso ho modificato lo script in opzione pass -t solo se è stato rilevato un terminale. Ecco il codice dopo le modifiche:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.