Come eseguire un comando in background senza output a meno che non si verifichi un errore


14

Come sopprimere l'output di un comando ma mostrarlo se il comando exit codifica un errore?

Risposte:


17

Sfortunatamente, il presupposto che stderrviene utilizzato solo per l'output degli errori non è sempre corretto. Piuttosto, stderrviene spesso utilizzato per qualsiasi output interattivo e diagnostica, ovvero output destinato all'utente a leggere in un prompt interattivo 1 . wgetedd sono esempi ben noti.

Alcuni comandi forniranno un flag (ad es. -quietO -silent) per sopprimere l'output senza errori - leggi le loro pagine man per vedere se ne esiste uno.


Un'altra convenzione che vale più spesso è il codice di uscita : un programma restituisce un codice di uscita quando esce. In genere 2 , un codice di uscita di0 indica successo, e qualsiasi altro codice di uscita indica un errore.

Con bash, è possibile ottenere il codice di uscita dell'ultimo comando dalla $?variabile. In fish, usa la $statusvariabile. È possibile reindirizzare stderra un file temporaneo e stamparlo solo se si verifica un errore. Ad esempio ( fish):

command 2>/tmp/outputbuffer
if $status
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

Puoi anche usare alcune scorciatoie, se non stai concatenando i comandi:

if command 2>/tmp/outputbuffer
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

O:

command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;

È inoltre possibile reindirizzare stdoutallo stesso buffer utilizzando 2>&1 >/tmp/outputbuffer.

(Nota: in realtà non lo so fish, quindi sto adattando il concetto a ciò che posso trovare nella sua documentazione. La sintassi potrebbe essere leggermente sbagliata. Inoltre, è possibile utilizzare mktempper generare un file temporaneo univoco: eseguirlo e registrare il nome file in una variabile.)

Se hai bisogno di eseguire tutto sullo sfondo di una shell che stai anche usando in modo interattivo allo stesso tempo, allora è meglio scrivere uno script per gestire l'output-hiding ed eseguire quello script in background con le tecniche standard ( fish). Diamine, puoi inserire qualcosa come la seguente funzione in ~/.config/fish/config.fish:

function run-silent
    set temp (mktemp)
    if $argv 2>&1 >$temp
        cat $temp
    rm $temp
end

Chiama con run-silent somecommand &(dove il trailing lo &fa funzionare in background)

Si noti che ciò inghiottirà il codice di uscita originale e scaricherà entrambi stdoute stderrin caso di errore. Puoi personalizzarlo come necessario.


1 Non c'è nemmeno la garanzia che l'output dell'errore non appaia stdout- alcuni programmi scaricheranno tutto l'output lì!

2 Sfortunatamente, questo non è sempre il caso: il codice di uscita è completamente controllato dal programma e alcuni indicano alcune condizioni di successo con uscite diverse da zero. Ancora una volta, controlla il manuale.


leggera modifica del pesce, c'è un posto speciale per mettere le funzioni in ~ / .config / fish / funzioni /
Xster

12

Le utility Unix inviano messaggi generali stdoute messaggi di errore a stderr, quindi se vogliamo vedere solo messaggi di errore, sarà sufficiente sopprimere stdoutsolostderr ottenere output sulla console.

Il modo per farlo (in entrambi bashe fish) è aggiungere>/dev/null al comando. Questo pipe stdout nel nulla, ma stderr (con i tuoi messaggi di errore) arriva ancora attraverso la console.

Quindi per esempio:

Il comando echo 1 >/dev/nullnon stampa nulla, perché il normalestdout output è soppresso e nulla è stato scritto su stderr.

Il comando man doesnotexist >/dev/nullstampa un messaggio di errore, perché manscrive il suo messaggio di errore in stderr.


2

Questo eseguirà il comando in background e scriverà errori in un file di registro ignorando l'output normale

    command > /dev/null 2> /tmp/example_error.log &
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.