Digamos que eu execute um comando ou script de shell, e isso me dá uma saída. Sem conhecer os elementos internos desse comando ou script de shell, como determinar se a saída foi de stderr
ou stdout
?
Por exemplo,
$ ls -ld /
drwxrwxr-t 35 root admin 1258 Dec 11 19:16 /
vs
ls -ld /test
ls: /test: No such file or directory
Como posso verificar se o primeiro comando foi impresso em stdout
e o segundo em stderr
(foi?)?
io-redirection
KM.
fonte
fonte
stderred
no seu ambiente shellLD_PRELOAD
para obterstdout
estderr
em cores diferentes. Aqui está uma pergunta relacionada nesse sentido.Respostas:
Não há como saber quando a saída já foi impressa. Nesse caso, ambos
stdout
estderr
estão conectados ao terminal, portanto, as informações sobre qual fluxo foi gravado já estavam perdidas quando o texto apareceu no seu terminal; eles foram combinados pelo programa antes mesmo de chegar ao terminal.O que você pode fazer, em um caso como o acima, seria executar o comando
stdout
estderr
redirecionar para lugares diferentes e ver o que acontece. Ou execute-o duas vezes, uma vez comstdout
redirecionado para/dev/null
e uma vez comstderr
redirecionado para/dev/null
, e veja qual desses casos resulta no texto sendo exibido.Você pode redirecionar
stdout
para/dev/null
alinhavando>/dev/null
no final da linha de comando estderr
para redirecionar/dev/null
adicionando2>/dev/null
.fonte
Você pode redirecionar o stdout usando
> file
e redirecionar stderr usando2> file
. Muitos shells modernos oferecem suporte ao redirecionamento para comandos, para que você possased
destacar qual saída vem de qual fluxo:fonte
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
O
annotate-output
script do Debiandevscripts
permite que você faça isso seletivamente:A segunda coluna indica stdout e stderr com
O
eE
respectivamente.Existem algumas advertências, a principal delas, conforme observado nas outras respostas: você não pode fazer isso depois do fato. Nem o shell nem o terminal sabem como um programa arbitrário usa seus descritores de arquivo, embora o shell seja responsável por configurá-los inicialmente.
Esse método usa fifos, escrever para um fifo pode se comportar de maneira diferente do que escrever para um tty, e escrever para dois fifos diferentes é definitivamente diferente (possíveis problemas de tempo / intercalação). Além disso, não é adequado para uso interativo, por exemplo,
annotate-output bash
não é um ótimo plano, mas é útil para muitos outros fins. Existem muitos exemplos de scripts e funções de shell em respostas a perguntas relacionadas sobre a colorização de stdin / stdout / stderr. O mais robusto é stderrd, que usa a modificação do tempo de execução da (maioria) dos programas para modificar os dados gravados no stderr.Esta pergunta à qual Anko se vincula tem boas respostas sobre esse tema relacionado: colorindo a saída stdout / stderr: Posso configurar meu shell para imprimir STDERR e STDOUT em cores diferentes?
fonte
bash
script usandowhile read
loops e executando umdate
comando para cada linha de stdout ou stderr, portanto será muito menos eficiente que ocmd > >(ts '%T O:') 2> >(ts '%T E:')
equivalente.Além das outras respostas, é interessante apontar para
/proc/$PID/fd
(embora não responda à pergunta):Como você vê, aqui você pode ver os descritores de arquivo abertos para um processo.
0
é oSTDIN
,1
é oSTDOUT
e2
é oSTDERR
. Se você não redirecionou o STDOUT ou o STDERR, verá/dev/pts/33
(pelo menos neste exemplo) porque eles apontariam para o terminal.notas :
/proc/$PID
existe apenas para processos em execução. Nesse caso, useicat
sem argumentos para que não termine até fechar oSTDIN
. Também o executei em segundo plano e, portanto, tenho o PID imediatamente por causa deste exemplo.fonte
Não está claro o que você está perguntando, mas isso pode ajudar
Fonte
Se o código de saída for 0, significa simplesmente que o comando foi executado corretamente (stdout), aqui você pode encontrar significados se o código de saída for diferente de 0 (stderr)
fonte
stdout
e diferente de zerostderr
?stderr
e retornar um bom código de erro ou de gravarstdout
e retornar um código de erro incorreto. De fato, tentefind /root
- supondo que você não esteja executando como root, você deve imprimir 2 linhas - "/ root" será impressostdout
e "find: / root: Permissão negada" será impressostderr
. E find retorna um código de retorno incorreto.Normalmente, o STDERR terá o nome do programa anexado à mensagem com dois pontos.
Exemplo:
Vs
fonte
Para capturar e testar a saída de erro:
fonte