Come reindirizzare l'output di qualsiasi comando?


14

Sto cercando di scrivere un semplice script per monitorare lo stato della mia rete, senza tutto pingl'output:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

Il problema è che quando non sono collegato, ricevo ancora un messaggio di errore nel mio output:

ping: unknown host google.com
offline

Come posso mantenere questo messaggio di errore fuori dal mio output?

Risposte:


28

Quando corri:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

Stai essenzialmente reindirizzando l'output dello Stream 1 (cioè stdout) a /dev/null.

Questo va bene quando si desidera reindirizzare l'output prodotto dalla normale esecuzione di un programma. Tuttavia, nel caso in cui si desideri reindirizzare anche l'output causato da tutti gli errori, avvisi o guasti, è necessario reindirizzare il stderrflusso o Errore standard a /dev/null.

Un modo per farlo è anteporre il numero dello stream che si desidera reindirizzare all'operatore di reindirizzamento, in >questo modo:Command 2> /dev/null

Quindi, il tuo comando sarebbe simile a:

ping -q -c 1 google.com > /dev/null 2> /dev/null && echo online || echo offline

Tuttavia, tieni presente che abbiamo già reindirizzato uno stream a /dev/null. Perché non semplicemente sulle spalle sullo stesso reindirizzamento? Bash ci consente di farlo specificando il numero di flusso a cui reindirizzare. 2>&1.

Notare il &carattere dopo l'operatore di reindirizzamento. Questo dice alla shell che ciò che appare dopo non è un nome file, ma un identificatore per il flusso di output.

ping -q -c 1 google.com > /dev/null 2>&1  echo online || echo offline

Fai attenzione con gli operatori di reindirizzamento, il loro ordine è molto importante. Se dovessi reindirizzare nell'ordine sbagliato, otterrai risultati inaspettati.

Un altro modo in cui è possibile ottenere il silenzio completo è reindirizzare tutti i flussi di output /dev/nullall'utilizzo di questo collegamento: &>/dev/null(o reindirizzare a un file di registro con &>/path/to/file.log).

Quindi, scrivi il tuo comando come:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline

1
Ah &>/dev/nulllo è. Grazie a tutti per l'aiuto istantaneo!
operalala,

4
Be careful with the redirection operators, their order matters a lot., ma non hai incluso un esempio di utilizzo effettivo2>&1
Izkata,

Mi ero dimenticato di aggiungerlo! Risposta modificata per riflettere l'esempio. Quando avrò ancora un po 'di tempo a disposizione, spiegherò come funziona anche l'ordinamento.
Darnir,

9

È necessario reindirizzare sia l'output standard ( >o 1>) sia l'errore standard ( 2>):

ping -q -c 1 google.com > /dev/null 2>/dev/null && echo online || echo offline

oppure, reindirizzare l'uno all'altro:

ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline

8
$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline

Esempi

$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
online

$ ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline
offline

Accelerare il ping

A seconda pingdell'implementazione potresti essere limitato a un singolo conteggio -c 1. Alcune implementazioni ti permetteranno di andare al di sotto di questo, ma essenzialmente devi aspettare che scadano le ricerche sbagliate. Quindi invece di usare pingpotresti voler usare finginvece.

lentezza del ping non riuscita

$ date; ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:10 EST 2014
online
Tue Jan 28 13:51:10 EST 2014

$ date; ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:15 EST 2014
offline
Tue Jan 28 13:51:25 EST 2014

fing è molto più veloce a fallire

$ date; fing -p google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:21 EST 2014
online
Tue Jan 28 13:49:22 EST 2014

$ date; fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:35 EST 2014
online
Tue Jan 28 13:49:38 EST 2014

1
Preferirei usare il timecomando piuttosto che calcolare manualmente la differenza di tempo con date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Ruslan,

@Ruslan - grazie, l'ho fatto in questo modo b / c di cui volevo l'uscita date. È più facile, IMO, per qualcun altro leggere l'output generato.
slm
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.