Redirecionando fluxos no shell bash - como tornar incondicional o resto da linha de comando do shell

1

Observei que apt output é diferente quando executado sozinho no shell Bash e quando a saída é redirecionada para os arquivos.

Por exemplo:

$ apt install ./*.deb --simulate 1>111.txt 2>222.txt

adicionando resultados de redirecionamento no texto WARNING: apt does not have a stable CLI interface. Use with caution in scripts. no arquivo para o fluxo 2, enquanto a execução do redirecionamento apt w / out não exibe este texto na janela do shell.

Por que a saída depende do redirecionamento? Talvez apt veja o redirecionamento como seu parâmetro? Como posso escrever o redirecionamento para passar despercebido para outra parte da linha de comando do shell?

P.S. Eu vi no Ubuntu 18 e apt é um aplicativo específico, mas talvez o problema seja geral para o Unix, então coloquei apenas shell na tag.

    
por Alexei Martianov 04.08.2018 / 15:55

2 respostas

2

apt foi projetado historicamente com o uso interativo de linha de comando em mente, daí o aviso codificado, que foi feito intencionalmente em / por apt e não pelo shell.

No entanto, apt não está necessariamente analisando a linha de comando; o shell já fez esse trabalho no momento em que chama apt . O que o apt está fazendo é detectar que o fluxo stdout foi alterado / redirecionado.

Quanto ao uso de apt em scripts, você tem o comando anterior mais antigo apt-get , que faz mais ou menos a mesma coisa, e não fornece esse aviso quando stdout é redirecionado.

TLDR Não é o shell que está gravando a mensagem de erro em stderr , é o comando apt .

O fato de você ser capaz de capturar a saída apt stderr no shell é um artefato do Unix sendo um sistema operacional multitarefa, e não significa que seja o shell que produz essa saída.

PS. Fazendo um strace no comando, pode ser visto apt escrevendo essa mensagem:

strace apt get install bash > a
....
write(2, "\n", 1
)                       = 1
write(2, "WARNING: ", 9WARNING: )                = 9
write(2, "apt", 3apt)                      = 3
write(2, " ", 1 )                        = 1
write(2, "does not have a stable CLI inter"..., 38does not have a stable CLI interface. ) = 38
write(2, "Use with caution in scripts.", 28Use with caution in scripts.) = 28
write(2, "\n", 1
)                       = 1
write(2, "\n", 1
)                       = 1
    
por 04.08.2018 / 16:00
0

"How can I write redirection to be unnoticed to other part of shell command line?"

Você não precisa fazer nada, o aviso está no stdErr. Tente isto:

apt list adghdgd | grep .
2>/dev/null apt list adghdgd | grep .

Se as cores de sua distribuição forem grep por padrão, você verá que a parte que realmente vai para o grep será colorida. Na segunda forma stdErr fica suprimido alltoghether.

O Grep também se comporta de maneira diferente, compare isso:

echo hello | grep .
echo hello | grep . | cat

O segundo formulário não é colorido, porque o grep percebe que seu stdOut não é um terminal, mas um pipe. Como ele / ela sabe ????

Compare

ls -l /proc/self/fd/1
( ls -l /proc/self/fd/1 ) | cat

No primeiro formulário, stdOut é tty / pts. No segundo, um cano.

    
por 14.08.2018 / 02:15