Este é um comando que funciona:
$ echo 'hi there' | docker run -i ubuntu cat
hi there
Este é um comando que responde com uma mensagem de erro:
$ echo 'hi there' | docker run -it ubuntu cat
the input device is not a TTY
Eu gostaria de descobrir exatamente o que acontece aqui. Não apenas "remova -t e será corrigido".
Eu sei que docker run
's -t
opção significa 'Alocar um pseudo-TTY', e eu li resumos históricos de que TTY significa , mas não me ajudar a compreender que tipo de contrato é violado aqui.
-t
, mas não consigo modificar o comando docker start em produção. Então, preciso fazer com que o aplicativo pense que foi iniciado-t
.Respostas:
Essa resposta me ajudou a entender:
-i
nem-t
opções), um contêiner do Docker envia apenas sua saída para STDOUT,-i
opção vem conexão com STDIN,-t
A opção puxa um driver de interface de terminal , que funciona em cima de STDIN / STDOUT. E quando um driver de terminal é acionado, a comunicação com um contêiner deve estar em conformidade com o protocolo da interface do terminal . Tubulação de uma cadeia não.fonte
Resposta tardia, mas pode ajudar alguém
docker run/exec -i
conectará o STDIN do comando dentro do contêiner ao STDIN dodocker run/exec
próprio.então
docker run -i alpine cat
fornece uma linha vazia aguardando entrada. Digite "olá" para obter um eco "olá". O contêiner não sairá até você enviar CTRL + D porque o processo principalcat
está aguardando a entrada do fluxo infinito que é a entrada do terminaldocker run
.echo "hello" | docker -i run alpine cat
, imprimirá "olá" e sairá imediatamente, porquecat
percebe que o fluxo de entrada terminou e termina automaticamente .Se você tentar
docker ps
depois de sair de qualquer um dos itens acima, não encontrará nenhum contêiner em execução. Nos dois casos,cat
ele próprio foi finalizado, portanto, a janela de encaixe finalizou o contêiner.Agora, para "-t", isso diz ao processo principal dentro da janela de encaixe que sua entrada é um dispositivo terminal.
então
docker run -t alpine cat
fornecerá uma linha vazia, mas se você tentar digitar "olá", não receberá eco. Isso ocorre porque enquantocat
estiver conectado a uma entrada do terminal, essa entrada não estará conectada à sua entrada. O "olá" que você digitou não atingiu a entrada decat
.cat
está aguardando uma entrada que nunca chega.echo "hello" | docker run -t alpine cat
também fornecerá uma linha vazia e não sairá do contêiner no CTRL-D, mas você não receberá um "alô" de eco porque não passou-i
Se você enviar CTRL + C, recupera seu shell, mas se tentar
docker ps
agora, verá ocat
contêiner ainda em execução. Isso ocorre porquecat
ainda está aguardando um fluxo de entrada que nunca foi fechado. Eu não encontrei nenhum uso útil para o-t
sozinho, sem ser combinado com-i
.Agora,
-it
juntos. Isso informa ao gato que sua entrada é um terminal e ao mesmo tempo conecta esse terminal à entrada dadocker run
qual é um terminal.docker run/exec
garantirá que sua própria entrada seja realmente um tty antes de passá-la paracat
. É por isso que você obterá uminput device is not a TTY
se tentar,echo "hello" | docker run -it alpine cat
porque nesse caso, a entrada emdocker run
si é o canal do eco anterior e não o terminal ondedocker run
é executadoPor fim, por que você precisaria passar
-t
se-i
fará o truque de conectar sua entrada àcat
entrada de? Isso ocorre porque os comandos tratam a entrada de maneira diferente se for um terminal. Isso também é melhor ilustrado pelo exemplodocker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
fornecerá uma solicitação de senha. Se você digitar a senha, os caracteres serão impressos visivelmente.docker run -i alpine sh
lhe dará uma linha vazia. Se você digitar um comando comols
obtém uma saída, mas não receberá uma saída rápida ou colorida.Nos dois últimos casos, você tem esse comportamento porque
mysql
, assim comoshell
não estavam tratando a entrada como um tty e, portanto, não utilizar tty comportamento específico como mascarar a entrada ou colorir a saída.fonte
Um tty indica que você possui um terminal, algo que seria fornecido pelo xterm ou por uma das muitas interfaces de linha de comando do linux. Ele precisa de uma interface de saída de teclado e texto associada a ele. Os motivos típicos para isso são o suporte à saída de texto colorido, o manuseio de várias combinações de teclas (como as teclas de seta) e a capacidade de mover o cursor pela tela.
Quando você canaliza um comando na janela de encaixe, como
echo
mostra o exemplo, esse canal é a entrada e esse canal não possui uma interface tty, é apenas um fluxo de texto. A tentativa de criar um tty com isso falhará como a mensagem de erro indica.fonte