Wie leite ich die Ausgabe eines Befehls um?

14

Ich versuche ein einfaches Skript zu schreiben, um meinen Netzwerkstatus zu überwachen, ohne die gesamte pingAusgabe:

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

Das Problem ist, dass wenn ich nicht verbunden bin, immer noch eine Fehlermeldung in meiner Ausgabe angezeigt wird:

ping: unknown host google.com
offline

Wie kann ich diese Fehlermeldung aus meiner Ausgabe heraushalten?

Operalala
quelle

Antworten:

28

Wenn du rennst:

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

Sie leiten im Wesentlichen nur die Ausgabe von Stream 1 (dh stdout) an um /dev/null.

Dies ist in Ordnung, wenn Sie die Ausgabe umleiten möchten, die bei der normalen Ausführung eines Programms erzeugt wird. Wenn Sie jedoch auch die Ausgabe umleiten möchten, die durch alle Fehler, Warnungen oder Ausfälle verursacht wurde, sollten Sie auch die umleitenstderr Stream oder Standardfehler an/dev/null .

Eine Möglichkeit hierfür ist das Voranstellen der Nummer des Streams, den Sie an den Umleitungsoperator umleiten möchten. > wie :Command 2> /dev/null

Daher würde Ihr Befehl so aussehen:

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

Beachten Sie jedoch, dass wir bereits einen Stream an umgeleitet haben /dev/null . Warum nicht einfach bei der gleichen Umleitung huckepack nehmen? Mit Bash können wir dazu die Stream-Nummer angeben, zu der umgeleitet werden soll. 2>&1.

Beachten Sie das &Zeichen nach dem Umleitungsoperator. Dies teilt der Shell mit, dass als Nächstes kein Dateiname, sondern ein Bezeichner für den Ausgabestream angezeigt wird.

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

Seien Sie vorsichtig mit den Umleitungsoperatoren, ihre Reihenfolge ist sehr wichtig. Wenn Sie in der falschen Reihenfolge umleiten, erhalten Sie unerwartete Ergebnisse.

Eine andere Möglichkeit, vollständige Stille zu erreichen, besteht darin, alle Ausgabestreams auf /dev/nulldiese Verknüpfung &>/dev/nullumzuleiten : (oder in eine Protokolldatei mit umzuleiten &>/path/to/file.log).

Schreiben Sie Ihren Befehl daher wie folgt:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline
verdammt
quelle
1
Aha ist &>/dev/nulles. Vielen Dank für die sofortige Hilfe!
Operalala
4
Be careful with the redirection operators, their order matters a lot., aber Sie haben kein Beispiel für die tatsächliche Verwendung von2>&1
Izkata
Ich hatte vergessen, das hinzuzufügen! Die Antwort wurde bearbeitet, um das Beispiel wiederzugeben. Wenn ich etwas mehr Zeit habe, erkläre ich, wie die Bestellung auch funktioniert.
Darnir
9

Sie müssen sowohl die Standardausgabe ( >oder 1>) als auch den Standardfehler ( 2>) umleiten :

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

oder leiten Sie eines zum anderen um:

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

Beispiele

$ 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

Ping beschleunigen

Abhängig von Ihrer pingImplementierung sind Sie möglicherweise auf eine einzelne Anzahl beschränkt -c 1. Bei einigen Implementierungen können Sie darunter vorbeigehen, aber Sie müssen im Wesentlichen auf schlechte Suchvorgänge warten, bis die Zeit abgelaufen ist. Anstatt also zu verwenden ping, möchten Sie vielleicht fingstattdessen verwenden.

Langsamkeit der Ping-Fehler

$ 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 ist viel schneller zu scheitern

$ 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
quelle
1
Ich würde lieber einen timeBefehl verwenden als die Zeitdifferenz manuell zu berechnen mit date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Ruslan
@ Ruslan - danke, ich habe es so gemacht, wie ich es wollte date. Es ist einfacher, IMO, die generierte Ausgabe zu lesen.
SLM