Nota:
- Diese Antwort geht wahrscheinlich tiefer, als es der Anwendungsfall rechtfertigt, und
find 2>/dev/null
kann in vielen Situationen gut genug sein . Er kann dennoch von Interesse sein, weil er eine plattformübergreifende Perspektive bietet und einige fortgeschrittene Shell-Techniken diskutiert, um eine möglichst robuste Lösung zu finden, auch wenn die Fälle, vor denen man sich schützen will, weitgehend hypothetisch sind.
Wenn Ihr Schale ist bash
o zsh
gibt es eine Lösung, die robust und gleichzeitig relativ einfach ist , mit nur POSIX-konforme find
Merkmale ; während bash
selbst ist nicht Teil von POSIX, aber die meisten modernen Unix-Plattformen bringen es mit, was diese Lösung weitgehend portabel macht:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Nota:
-
Wenn Ihr System so konfiguriert ist, dass es Folgendes anzeigt lokalisiert Fehlermeldungen, vorangestellt ist die find
ruft unten mit LC_ALL=C
( LC_ALL=C find ...
), um sicherzustellen, dass Englisch Nachrichten gemeldet werden, so dass grep -v 'Permission denied'
funktioniert wie vorgesehen. Allerdings werden alle Fehlermeldungen, die hacer werden dann auch in Englisch angezeigt.
-
>(...)
ist eine (selten verwendete) Ausgabe Prozesssubstitution die es erlaubt, die Ausgabe umzuleiten (in diesem Fall, stderr Ausgabe ( 2>
) an die stdin des Befehls in >(...)
.
Zusätzlich zu bash
y zsh
, ksh
unterstützt auch sie prinzipiell aber der Versuch, sie mit der Umleitung von stderr wie es hier der Fall ist ( 2> >(...)
), scheint stillschweigend ignoriert zu werden (in ksh 93u+
).
-
grep -v 'Permission denied'
filtert aus ( -v
) alle Zeilen (vom find
des Befehls stderr), die die Phrase Permission denied
und gibt die restlichen Zeilen auf stderr aus ( >&2
).
-
Hinweis: Es besteht eine kleine Chance, dass einige der grep
kann die Ausgabe von nach find
abgeschlossen wird, da der Gesamtbefehl nicht auf den Befehl innerhalb von >(...)
zu beenden. Unter bash
können Sie dies durch Anhängen von | cat
zum Befehl.
Dieser Ansatz ist:
-
robust : grep
wird nur angewendet auf Fehlermeldungen (und nicht auf eine Kombination von Dateipfaden und Fehlermeldungen, was zu Fehlalarmen führen könnte), und andere Fehlermeldungen als solche mit verweigerter Berechtigung werden an stderr weitergeleitet.
-
Nebenwirkungsfrei : find
wird beibehalten: Die Unfähigkeit, auf mindestens eines der angetroffenen Dateisystemelemente zuzugreifen, führt zu dem Exit-Code 1
(obwohl das nichts darüber aussagt, ob Fehler andere als (auch) verweigerte Genehmigungen).
POSIX-konforme Lösungen:
Vollständig POSIX-konforme Lösungen haben entweder Einschränkungen oder erfordern zusätzlichen Aufwand.
Si find
Die Ausgabe des Programms ist in einer ファイル trotzdem (oder ganz unterdrückt), dann wird die Pipeline-basierte Lösung von Die Antwort von Jonathan Leffler ist einfach, robust und POSIX-konform:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Beachten Sie, dass die Reihenfolge der Umleitungen wichtig ist: 2>&1
muss kommen erste .
Die Erfassung der stdout-Ausgabe in einer Datei ermöglicht 2>&1
zu senden sólo Fehlermeldungen durch die Pipeline, die grep
kann dann eindeutig operieren.
El Der einzige Nachteil ist, dass die Gesamtausgangscode wird die grep
Der Befehl , nicht find
Das bedeutet in diesem Fall: Wenn es keine Fehler überhaupt nicht oder sólo Bei Fehlern, bei denen die Erlaubnis verweigert wurde, lautet der Exit-Code 1
(Signalisierung Ausfall ), andernfalls (andere Fehler als solche, bei denen die Erlaubnis verweigert wurde) 0
- was das Gegenteil der Absicht ist.
Davon abgesehen, find
Der Exit-Code wird ohnehin selten verwendet. da sie oft nur wenige Informationen vermitteln grundlegend Fehler wie die Übergabe eines nicht existierenden Pfades.
Allerdings ist der besondere Fall, dass sogar nur un peu de die Eingabepfade sind aufgrund fehlender Berechtigungen unzugänglich ist reflektiert in find
Exit-Code (sowohl in GNU als auch in BSD find
): Wenn ein Fehler bezüglich der verweigerten Berechtigungen für jede der verarbeiteten Dateien, wird der Exit-Code auf 1
.
Die folgende Variante geht darauf ein:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Jetzt zeigt der Exit-Code an, ob Fehler aufgetreten sind andere als Permission denied
aufgetreten: 1
wenn ja, 0
sonst.
Mit anderen Worten: Der Exit-Code spiegelt nun die wahre Absicht des Befehls wider: Erfolg ( 0
) wird gemeldet, wenn überhaupt keine Fehler oder sólo Fehler mit verweigerter Erlaubnis aufgetreten.
Dies ist wohl noch besser als das bloße Überholen find
Exit-Code durch, wie in der Lösung oben.
gniourf_gniourf in den Kommentaren schlägt eine (immer noch POSIX-konforme) Verallgemeinerung dieser Lösung durch ausgeklügelte Umleitungen die funktioniert auch mit dem Standardverhalten, die Dateipfade nach stdout :
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
Kurz gesagt: Benutzerdefinierter Dateideskriptor 3
wird verwendet, um stdout vorübergehend auszulagern ( 1
) und stderr ( 2
), so dass Fehlermeldungen allein kann über Rohrleitungen an grep
über stdout.
Ohne diese Umleitungen werden sowohl Daten (Dateipfade) と Fehlermeldungen würden über eine Pipeline an grep
über stdout, und grep
würde dann nicht mehr unterscheiden können zwischen Fehlermeldung Permission denied
und eine (hypothetische) Datei, deren Name zufällig Folgendes enthält der Satz Permission denied
.
Wie bei der ersten Lösung wird jedoch der folgende Exit-Code gemeldet grep
ist, nicht find
aber die gleiche Lösung wie oben kann angewendet werden.
Anmerkungen zu den vorhandenen Antworten:
-
Es gibt mehrere Punkte, die zu beachten sind Die Antwort von Michael Brux , find . ! -readable -prune -o -print
:
-
Sie erfordert GNU find
Vor allem funktioniert es nicht unter macOS. Natürlich, wenn Sie den Befehl nur brauchen, um mit GNU zu arbeiten find
wird dies kein Problem für Sie sein.
-
Einige Permission denied
Fehler können immer noch Oberfläche: find ! -readable -prune
meldet solche Fehler für die Kind Elemente von Verzeichnissen, für die der aktuelle Benutzer über r
Erlaubnis, aber es fehlt x
(ausführbare) Berechtigung. Der Grund dafür ist, dass das Verzeichnis selbst ist lesbar, -prune
wird nicht ausgeführt, und der Versuch des Abstiegs に dieses Verzeichnis löst dann die Fehlermeldungen aus. Das heißt, die typisch Fall ist für die r
die Erlaubnis, zu fehlen.
-
Hinweis: Der folgende Punkt ist eine Frage der Philosophie und/oder des spezifischen Anwendungsfalls, und Sie können entscheiden, dass er für Sie nicht relevant ist und dass der Befehl Ihren Bedürfnissen gut entspricht, insbesondere wenn Sie einfach Drucken die Wege sind alles, was Sie tun:
- Wenn Sie konzipieren die Filterung der Fehlermeldungen über verweigerte Genehmigungen als getrennt Aufgabe, auf die Sie sich bewerben möchten jede
find
Befehl, dann der umgekehrte Ansatz, nämlich proaktiv Verhütung Fehler, für die keine Erlaubnis erteilt wurde, erfordern die Einführung von "Rauschen" in die find
Befehl, der ebenfalls Komplexität und Logik mit sich bringt Fallstricke .
- Der am meisten bewertete Kommentar zu Michaels Antwort (zum Zeitpunkt der Erstellung dieses Artikels) versucht beispielsweise zu zeigen, wie man erweitern. den Befehl durch Einfügen eines
-name
Filter, wie folgt:
find . ! -readable -prune -o -name '*.txt'
Dies bedeutet jedoch no wie vorgesehen funktionieren, da die nachgestellten -print
Aktion ist erforderlich (eine Erklärung finden Sie in diese Antwort ). Solche Feinheiten können zu Fehlern führen.
-
Die erste Lösung in Die Antwort von Jonathan Leffler , find . 2>/dev/null > files_and_folders
wie er selbst sagt, blindlings schweigt 何れも Fehlermeldungen (und die Umgehung ist umständlich und nicht ganz stabil, wie er auch erklärt). Pragmatisch gesprochen Es ist jedoch die einfachste Lösung da Sie davon ausgehen können, dass alle Fehler auf die Erlaubnis zurückzuführen sind.
-
Antwort des Nebels , sudo find . > files_and_folders
, ist prägnant und pragmatisch, aber schlecht geeignet für etwas anderes als nur Drucken Dateinamen aus Sicherheitsgründen: weil Sie als der Wurzel Benutzer, "riskieren Sie, dass Ihr ganzes System durch einen Fehler in find oder eine bösartige Version durcheinander gebracht wird, oder durch einen falschen Aufruf, der etwas unerwartet schreibt, was nicht passieren könnte, wenn Sie dies mit normalen Rechten ausführen würden" (aus einem Kommentar zu Mist's Antwort von tripleee ).
-
Die 2. Lösung in viraptor's Antwort , find . 2>&1 | grep -v 'Permission denied' > some_file
birgt das Risiko von Fehlalarmen (da eine Mischung aus stdout und stderr durch die Pipeline geschickt wird), und möglicherweise wird statt der Meldung nicht -verweigerte Fehler über stderr, erfasst sie zusammen mit den Ausgabepfaden in der Ausgabedatei.
0 Stimmen
Tolle Frage! Leider funktionieren die ersten drei Antworten einfach nicht unter Debian Linux. Oder zumindest meine Konfiguration davon. Ich brauchte Fatih's Lösung,
find /. -name 'toBeSearched.file' 2>/dev/null
.0 Stimmen
Ich fand es am besten, den
/proc
-Pfad mithilfe der-path
-Option auszuschließen. Es hilft, die-prune
-Option zu verneinen, um das Drucken von ausgeblendeten Elementen zu vermeiden.