Comment rediriger la sortie d'une commande?

14

J'essaie d'écrire un script simple pour surveiller l'état de mon réseau, sans toutes pingles sorties de:

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

Le problème est que lorsque je ne suis pas connecté, je reçois toujours un message d'erreur dans ma sortie:

ping: unknown host google.com
offline

Comment puis-je garder ce message d'erreur hors de ma sortie?

operalala
la source

Réponses:

28

Lorsque vous exécutez:

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

Vous redirigez essentiellement la sortie du flux 1 (c'est stdout-à- dire ) vers /dev/null.

C'est très bien lorsque vous souhaitez rediriger la sortie produite par l'exécution normale d'un programme. Cependant, si vous souhaitez également rediriger la sortie causée par toutes les erreurs, avertissements ou échecs, vous devez également rediriger le stderrou le flux d'erreur standard vers /dev/null.

Une façon de procéder consiste à ajouter le numéro du flux que vous souhaitez rediriger à l'opérateur de redirection, >comme ceci:Command 2> /dev/null

Par conséquent, votre commande ressemblerait à:

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

Mais notez que nous avons déjà redirigé un flux vers /dev/null. Pourquoi ne pas simplement se greffer sur la même redirection? Bash nous permet de le faire en spécifiant le numéro de flux vers lequel rediriger. 2>&1.

Remarquez le &caractère après l'opérateur de redirection. Cela indique au shell que ce qui apparaît ensuite n'est pas un nom de fichier, mais un identifiant pour le flux de sortie.

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

Attention aux opérateurs de redirection, leur commande est très importante. Si vous deviez rediriger dans le mauvais ordre, vous vous retrouverez avec des résultats inattendus.

Vous pouvez également atteindre un silence complet en redirigeant tous les flux de sortie vers /dev/nullce raccourci: &>/dev/null(ou redirigez vers un fichier journal avec &>/path/to/file.log).

Par conséquent, écrivez votre commande comme suit:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline
darnir
la source
1
Ah &>/dev/nullc'est ça. Merci à tous pour l'aide instantanée!
operalala
4
Be careful with the redirection operators, their order matters a lot., mais vous n'avez pas inclus d'exemple d'utilisation 2>&1
réelle
J'avais oublié d'ajouter ça! Réponse modifiée pour refléter l'exemple. Lorsque j'aurai un peu plus de temps libre, je vous expliquerai également comment fonctionne la commande.
darnir
9

Vous devez rediriger la sortie standard ( >ou 1>) et l'erreur standard ( 2>):

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

ou, redirigez l'un vers l'autre:

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

Exemples

$ 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

Accélérer le ping

Selon votre pingimplémentation, vous pouvez être limité à un seul décompte -c 1. Certaines implémentations vous permettront d'aller en dessous, mais vous devez essentiellement attendre que les mauvaises recherches expirent. Donc, au lieu d'utiliser, pingvous voudrez peut-être utiliser à la fingplace.

lenteur de l'échec du ping

$ 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

le doigt est beaucoup plus rapide à échouer

$ 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
slm
la source
1
Je préfère utiliser la timecommande plutôt que de calculer manuellement le décalage horaire avec date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Ruslan
@Ruslan - merci, je l'ai fait de cette façon car je voulais la sortie de date. C'est plus facile, OMI, pour quelqu'un d'autre de lire la sortie générée.
slm