Erro "O dispositivo de entrada não é um TTY"

425

Estou executando o seguinte comando do meu Jenkinsfile. No entanto, recebo o erro "O dispositivo de entrada não é um TTY" .

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

Existe uma maneira de executar o script Jenkinsfilesem fazer o modo interativo?

Basicamente, tenho um arquivo chamado script.shque gostaria de executar dentro do contêiner do Docker.

Anthony
fonte
Para * nix, parece que não há solução aqui. 'docker exec -i' não funciona, nem '-t'.
Rjurney
1
@rjurney Você já encontrou uma solução para o docker exec? Eu tentei -i e -t sem sucesso. janela de encaixe exec -é myContainer festa certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch
@Hutch Desculpe, não me lembro :(
rjurney

Respostas:

639

Remova o -itseu CLI para torná-lo não interativo e remova o TTY. Se você também não precisar, por exemplo, executando seu comando dentro de um script Jenkins ou cron, faça isso.

Ou você pode alterá-lo para -ise tiver introduzido um canal no comando docker que não vem de um TTY. Se você tem algo parecido xyz | docker ...ou docker ... <inputna sua linha de comando, faça isso.

Ou você pode alterá-lo para -tse desejar suporte TTY, mas não o tiver disponível no dispositivo de entrada. Faça isso para formatação colorida da saída em seus logs ou quando você posteriormente conectar ao contêiner com um terminal adequado.

Ou se você precisar de um terminal interativo e não estiver executando em um terminal no Linux ou MacOS, use uma interface de linha de comando diferente. É relatado que o PowerShell inclui esse suporte no Windows.


O que é um TTY? É uma interface de terminal que suporta saída em cores, seqüências de escape, movimentação do cursor, etc., que vem dos velhos tempos de terminais burros conectados aos mainframes. Hoje, ele é fornecido pelos terminais de comando do Linux e pelas interfaces ssh. Veja o artigo da Wikipedia para mais detalhes .

BMitch
fonte
10
Estou usando este comando em conjunto com mysql -psem especificar uma senha. Ao adicionar -ia solicitação de senha, nunca aparece. Basta adicionar -to prompt, mas ele parece não ler a entrada (que é impressa literalmente em vez de oculta pelo prompt), nem mesmo ao pressionar return; somente ctrl-c pode finalizá-lo. É de alguma forma possível usar o cliente mysql com o docker dessa maneira?
ohcibi
95

Para aqueles que enfrentam esse erro e fazem o git bash no Windows, basta usar o PowerShell onde -itfunciona perfeitamente.

Piotr Justyna
fonte
12
Isso não responde à pergunta. A questão é sobre o docker no Jenkins, e não o git bash no Windows.
45
Bem. verdade, e nunca foi a intenção. A pergunta aparece no google quando você pesquisa essa mensagem de erro específica. Eu pensei, melhor ter a resposta em algum lugar do que não tê-la. Claramente algumas pessoas achei :) útil
Piotr Justyna
3
O problema com o Powershell como TTY para operações de shell é que ele não passa corretamente as teclas de seta, como a seta para cima para o histórico de comandos de ciclo. Funciona muito bem além dessa falha.
Corgalore 28/02
2
Se você quiser continuar usando o Git Bash, veja esta resposta em outra pergunta ou a resposta winpty abaixo
tessafyi
68

Não é exatamente o que você está perguntando, mas:

A tecla -T ajudaria as pessoas que estão usando o docker-compose exec!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup
yestema
fonte
2
Exatamente o que eu estava procurando. você sabe por que isso funciona?
Ulad Kasach 16/01
6
Apenas o que eu precisava também. De acordo com a ajuda: -T Desative a alocação de pseudo-tty. Por padrão, docker-compose exec aloca um TTY.
TS
Obrigado cara. Eu procuro por docker-compor!
ADyDyka
Isso funcionou para mim!
rlorenzo
59

Se você está (como eu) usando o git bash no Windows, basta colocar

winpty

antes da sua 'linha de encaixe':

winpty docker exec -it some_cassandra bash
Gremi64
fonte
como você baixa winpty?
Mor Shemesh
6
Você tentou antes de perguntar? Eu acho que ele vem com Git (o meu é dentro ... / Git / usr / bin)
Gremi64
Você está certo, está abaixoC:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh
31

Eu acredito que você precisa estar em um TTY para o docker para poder alocar um TTY (a -topção). Jenkins executa seus trabalhos não em um TTY.

Dito isto, o script que você está executando no Jenkins também pode ser executado localmente. Nesse caso, pode ser realmente conveniente ter um TTY alocado para que você possa enviar sinais como ctrl+ cao executá-lo localmente.

Para corrigir isso, faça seu script usar opcionalmente a -topção, assim:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...
Gareth A. Lloyd
fonte
Este erro acontecer comigo quando executando docker run…forma de comando uma tarefa makefile desencadeada por um gancho git
Édouard Lopez
1
essa deve ser a resposta aceita. ele realmente resolve o problema de uma maneira universalmente aplicável
roothahn
11

ao usar 'git bash',

1) Eu executo o comando:

docker exec -it 726fe4999627 /bin/bash

Eu tenho o erro:

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

2), então, eu executo o comando:

winpty docker exec -it 726fe4999627 /bin/bash

Estou com outro erro:

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) terceiro, eu executo o:

winpty docker exec -it 726fe4999627 bash

funcionou.

quando eu uso 'powershell', tudo funcionou bem.

Wangsir
fonte
Também bati minha cabeça na parede por algumas horas com esses problemas usando o bash. Mudou para o PowerShell e todos os trabalhos agora!
David Spenard
5

se estiver usando o windows, tente com o cmd, para mim funciona. verifique se a janela de encaixe foi iniciada.

Diego Santa Cruz Mendezú
fonte
1

O winpty funciona desde que você não especifique volumes a serem montados, como ".: / mountpoint" ou "$ {pwd}: / mountpoint"

A melhor solução alternativa que encontrei é usar o plug-in git-bash no Visual Code Studio e usar o terminal para iniciar e parar contêineres ou composição do docker.

Rusty1
fonte
1

Eu sei que isso não está respondendo diretamente à pergunta em questão, mas a qualquer pessoa que se deparar com essa pergunta que esteja usando o WSL executando o Docker para janelas e cmder ou conemu.

O truque é não usar o Docker, instalado no Windows em / mnt / c / Arquivos de programas / Docker / Docker / resources / bin / docker.exe, mas instalar o Docker ubuntu / linux. Vale ressaltar que você não pode executar o Docker em si na WSL, mas pode se conectar ao Docker for Windows a partir do cliente linux Docker.

Instale o Docker no 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

Conecte-se ao Docker for windows na porta 2375, que precisa ser ativada nas configurações no docker for windows.

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

Ou defina a variável docker_host que permitirá que você omita a opção -H

export DOCKER_HOST=tcp://localhost:2375

Agora você deve conseguir conectar-se interativamente com uma sessão de terminal tty.

Damo
fonte
0

Minha etapa do pipeline do Jenkins mostrada abaixo falhou com o mesmo erro.

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

No meu arquivo de script " build.sh ", o comando " docker run " gera esse erro quando foi executado pelo trabalho de Jenkins. No entanto, ele estava funcionando bem quando o script foi executado no terminal do shell. O erro ocorreu devido à opção -t passada para o comando docker run que, como eu sei, tenta alocar o terminal e falha se não houver um terminal para alocar.

No meu caso, alterei o script para passar a opção -t apenas se um terminal pudesse ser detectado. Aqui está o código após as alterações:

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
fonte