Tenho um script de shell iniciando um contêiner docker. Antes de iniciar o contêiner, ele inicia um loop em segundo plano imprimindo algumas linhas no terminal. Percebi que essas linhas impressas não retornam o cursor para o início da linha. O que descobri: isso acontece apenas durante o tempo de vida do contêiner. Veja o exemplo mínimo:
#!/usr/bin/env bash
cleanup() {
kill "${BACKGROUND_PROCESS}"
}
trap cleanup EXIT
backgroundLoop() {
while true; do
echo .
sleep 1
done
}
backgroundLoop &
BACKGROUND_PROCESS=$!
sleep 2
echo Starting docker
docker run --rm -it alpine sleep 5
echo Docker has finished
sleep 2
cleanup
A saída é:
.
.
Starting docker
.
.
.
.
.
.
Docker has finished
.
.
Alguém pode explicar por que isso acontece? Parece estar relacionado a esta pergunta , presumo que o docker reconfigure o TTY atual e o restaure depois. Isso está correto?
Remover -t
da chamada docker realmente corrige o problema, o que parece respaldar minha teoria. No entanto, preciso do TTY interativo para meu caso de uso real.
Como posso alterar meu código para que todas as linhas de saída sejam impressas com retornos de carro corretos?
ATUALIZAR :
Obtive uma resposta para essa pergunta que resolve o problema do meu exemplo mínimo postado acima, chamando stty -onocr
o contêiner docker antes do comando real.
Meu cenário do mundo real, no entanto, usa uma imagem docker personalizada com um script bash como ponto de entrada, então não posso passar comandos como argumentos. Exemplo mínimo do script entrypoint entrypoint.sh
:
#!/usr/bin/env sh
sleep 5
Em seguida, substitua a chamada do docker no script de teste
docker run --rm -it alpine sleep 5
com
docker run --rm -it -v ./entrypoint.sh:/entrypoint.sh --entrypoint /entrypoint.sh alpine
A saída é a mesma, mas a correção proposta não funciona neste caso. Alguma ideia de como aplicar a correção a este ambiente ligeiramente diferente?
Diga ao contêiner para não adicionar caracteres CR à saída, executando
stty -onocr
em seu contêiner alterando odocker run
comando paraPorque o executável do docker alterna o terminal para o modo raw ao gerar o terminal, como parte da
-t
opção que você passou para o docker run.Veja
man stty
https://en.wikipedia.org/wiki/Terminal_mode .Opção nº 1:
Você pode remover
-t
o sinalizador do docker run.Opção nº 2:
Você pode simplesmente definir
NORAW=1
a variável de ambiente.Consulte https://github.com/docker/cli/blob/068a01ea9470df6494cc92d9e64e240805ae47a7/cli/streams/in.go#L32 .
Opção nº 3:
Você pode reverter do modo raw, por exemplo com
stty -raw
. Algo junto:O primeiro
+ echo .
é impresso logo antesstty -raw
de poder acontecer. Depois-raw
, o terminal é cozido.Se você controla a linha de comando, você pode passar qualquer coisa como argumentos. Por exemplo: