Como suprimir a saída de um comando, mas mostrá-la se a saída do comando codifica um erro?
Infelizmente, a suposição que stderr
é usada apenas para saída de erro nem sempre é correta. Em vez disso, stderr
é frequentemente usado para toda e qualquer saída e diagnóstico interativo , ou seja, saída destinada ao usuário para ler em um prompt interativo 1 . wget
e dd
são exemplos bem conhecidos.
Alguns comandos fornecerão um sinalizador (por exemplo, -quiet
ou -silent
) para suprimir a saída sem erro - leia suas páginas de manual para ver se existe alguma.
Outra convenção que é mantida com mais frequência é o código de saída : um programa retorna um código de saída quando sai. Normalmente 2 , um código de saída 0
indica sucesso e qualquer outro código de saída indica um erro.
Com bash
, você pode obter o código de saída do último comando da $?
variável Em fish
, use a $status
variável Você pode canalizar stderr
para um arquivo temporário e imprimi-lo apenas se ocorrer um erro. Por exemplo ( fish
):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Você também pode usar alguns atalhos, se não estiver encadeando comandos:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Ou:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
Você também pode canalizar stdout
para o mesmo buffer usando 2>&1 >/tmp/outputbuffer
.
(Nota: na verdade eu não sei fish
, estou adaptando o conceito ao que posso encontrar na documentação. A sintaxe pode estar um pouco errada. Além disso, você pode usar mktemp
para gerar um arquivo temporário exclusivo - execute-o e grave o arquivo nome do arquivo em uma variável.)
Se você precisar executar a coisa toda em segundo plano de um shell que também estiver usando interativamente ao mesmo tempo, é melhor escrever um script para lidar com a ocultação de saída e executar esse script em segundo plano com as técnicas padrão ( fish
) Heck, você pode colocar algo como a seguinte função em ~/.config/fish/config.fish
:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
Ligar com run-silent somecommand &
(onde o final &
faz com que seja executado em segundo plano)
Note que isto irá engolir o código de saída original, e vai despejar tanto stdout
e stderr
em caso de uma falha. Você pode personalizá-lo conforme necessário.
1 Não há garantia de que a saída de erro não apareça stdout
- alguns programas despejam toda a saída lá!
2 Infelizmente, isso nem sempre é o caso - o código de saída é completamente controlado pelo programa e alguns indicarão algumas condições de sucesso com saídas diferentes de zero. Mais uma vez, verifique o manual.
Os utilitários Unix enviam mensagens gerais para
stdout
, e mensagens de erro parastderr
, portanto, se queremos apenas ver mensagens de erro, será suficiente suprimir,stdout
para que somente astderr
saída seja obtida no console.A maneira de fazer isso (nos dois
bash
efish
) é anexar>/dev/null
ao comando. Isso leva o stdout ao nada, mas o stderr (com suas mensagens de erro) ainda chega ao console.Então, por exemplo:
O comando
echo 1 >/dev/null
imprime nada, porque astdout
saída normal é suprimida e nada foi gravado no stderr.O comando
man doesnotexist >/dev/null
imprime uma mensagem de erro, porqueman
grava sua mensagem de erro emstderr
.fonte
Isso executará o comando em segundo plano e gravará erros em um arquivo de log que ignore a saída normal
fonte