Warum funktioniert dieser grep-Befehl nicht?

24

Wenn ich versuche, grep auf diese Weise zu verwenden:

service --status-all | grep network

Es werden weiterhin alle Dienste aufgelistet, obwohl ich sie weitergeleitet habe grep, um sie nur auf die Zeichenfolge "network" zu beschränken


Nach dem Fakt:

Als ich diesen Artikel bemerkte , der erklärt, warum sich der Befehl so verhält, mag ich das an Linux. Es gibt immer einen guten Grund, aber es ist nicht unbedingt intuitiv

Meer Borg
quelle

Antworten:

41

Versuchen:

service --status-all |& grep network

Befehlszeilenanwendungen können in zwei Textströmen drucken, die als Standardausgabe (stdout) und Standardfehler (stderr) bezeichnet werden. Standardmäßig zeigt das Terminal die Ausgabe für beide nur identisch an.

Stdout ist die Zahl 1, gegeben und stderr ist die Nummer 2. In der Standardeinstellung Umleitungsoperator gegeben, wie >, |und <gilt nur für stdout, Nummer 1.

|&Leiten Sie sowohl stdout als auch stderr zusammen an den Prozess im Standardeingabestream (stdin) des Rechts, sodass die grepArbeit wie erwartet ausgeführt wird.

Ich weiß nicht, warum service --status-allhier auf stderr gedruckt wird, aber im Allgemeinen ist es sehr nützlich, einen separaten stderr-Stream zu haben, da Sie Fehler sehen können, selbst wenn stdout stummgeschaltet ist.

Flimm
quelle
Vielen Dank für die Antwort, das scheint großes Interesse geweckt zu haben. Ich war wohl nicht der Einzige mit diesem Problem.
Meer Borg
4

Sie müssen standard error stream ( 2) auf standard output ( 1) umleiten :

service --status-all 2>&1 | grep network

Der Operator >leitet normalerweise zur Datei weiter (z 2>/tmp/file. B. ). Um mithilfe des Deskriptors zu einem anderen Stream umzuleiten , muss dieser mit vorangestellt werden &(beachten Sie, dass keine Leerzeichen zwischen den Zeichen stehen).

Paweł Nadolski
quelle