Verwenden von grep mit Pipe und kaufmännischem Und, um Fehler aus der Suche herauszufiltern

22

Ich verwende cygwin, um eine Datei auf dem cygdrive zu finden.

Ich muss jedoch die Nachrichten unterdrücken, denen die Berechtigung verweigert wurde (andernfalls werden die Ergebnisse in den Fehlermeldungen ausgeblendet). Der folgende Befehl funktioniert:

find -name 'myfile.*' |& grep -v "Permission denied"

Ich verstehe nicht, warum das kaufmännische Und in diesen Befehl eingefügt werden muss, hätte erwartet, dass dies funktioniert, aber es funktioniert nicht.

find -name 'myfile.*' | grep -v "Permission denied"

Bitte erläutern Sie die Bedeutung des Et-Zeichens.

Henrik K
quelle

Antworten:

24

In Unix-ähnlichen Systemen gibt es zwei Ausgabepfade, die, wenn sie nicht geändert werden, die Ausgabe an Ihren Bildschirm senden. Standardfehler (oder stderr) ist derjenige, der die meisten Fehler und Fehlerbedingungen erfasst.

Um die Meldung "Berechtigung verweigert" in "stderr" an denselben Ausgabestream wie "reguläre Ausgabe" zu übergeben, müssen Sie beide kombinieren. In Ihrem Beispiel grep -vkombinieren Sie stdout (Standardausgabe) und stderr mit der angezeigten arkanen Syntax, damit Sie ordnungsgemäß damit arbeiten können.

Aus dem GNU Bash-Handbuch, Abschnitt 3.2.2 Pipelines :

Wenn ' |&' verwendet wird, wird der Standardfehler von Befehl1 zusätzlich zu seiner Standardausgabe über die Pipe mit dem Standardeingang von Befehl2 verbunden . es ist eine Abkürzung für 2>&1 |. Diese implizite Umleitung des Standardfehlers zur Standardausgabe erfolgt nach allen vom Befehl angegebenen Umleitungen.

Außerdem, wie geirha betont, möchten Sie, wenn Sie nur die stderr-Ausgabe entfernen möchten, so etwas wie tun

find -name 'myfile.*' 2> /dev/null

oder vielleicht

find -name 'myfile.*' 2> /tmp/errorlog

Beachten Sie, dass Sie bei Befehlsfolgen, z. B. der findÜbergabe der Ausgabe an xargs, die gesamte Befehlspipeline in Klammern setzen müssen, um die Ausgabe aller Befehlskomponenten zu erfassen. Z.B,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Wenn Sie die Klammern weggelassen und dies stattdessen getan haben -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

Es werden weiterhin Fehler mit der Berechtigung "verweigert" in "find" oder "egrep" angezeigt, "stderr" wird jedoch für "xargs" umgeleitet.

Wie Sie gesehen haben, werden Sie den stderr wahrscheinlich erst dann wegwerfen, wenn Sie seinen Inhalt während eines Testlaufs angesehen haben.

Beachten Sie, dass bei GNU findund soweit ich das beurteilen kann, bei POSIX-kompatiblen finddie -printOption implizit ist. Sie können es trotzdem explizit angeben, wenn Sie möchten.

belacqua
quelle
Scheint nur bash4 + wiki.bash-hackers.org/bash4#redirection zu sein
Luke Exton
1
@ LukeExton Ja. In anderen Shells 2>&1 |kann anstelle von verwendet werden |&(dh man kann stderr explizit an stdout umleiten und dann an den nächsten Befehl in der Pipeline weiterleiten).
Eliah Kagan
2> >( grep filter )ist auch praktisch
user1133275
1

Wenn Sie die Fehlermeldungen ignorieren möchten, leiten Sie stderr einfach nach / dev / null um.

find . -name 'myfile.*' -print 2>/dev/null

Lesen Sie auch http://mywiki.wooledge.org/UsingFind .

geirha
quelle