Ich möchte wissen, ob ich mich auf das Verhalten verlassen kann, das ich bei der Verwendung find
mit -depth
Option sehe, und der Benutzer keine Ausführungsberechtigung für ein Unterverzeichnis hat.
Nehmen Sie die folgende Verzeichnisstruktur an:
drwxrwxrwt. 10 root root 12288 Mar 14 04:31 .
dr-xr-xr-x. 24 root root 4096 Dec 6 03:33 ..
drwx------ 4 root root 4096 Mar 14 04:03 jen
Führen Sie den folgenden Befehl als Nicht-Root-Benutzer aus:
find -type d
Die Ausgabe ist:
.
./jen
find: `./jen': Permission denied
Also find
fand das Verzeichnis jen und gab das aus. Es versuchte dann, in Jen abzusteigen , hatte aber keine Erlaubnis, so dass es den Fehler druckte. Die erste Zeile oben wird gedruckt stdout
und die zweite Zeile an stderr
.
Führen Sie nun Folgendes als Nicht-Root-Benutzer aus:
find -depth -type d
Und die Ausgabe ist:
find: `./jen': Permission denied
.
Daher wird der Pfadname nur ausgegeben, stdout
wenn der Benutzer die Berechtigung hat, den Inhalt des Verzeichnisses aufzulisten.
Diese Ausgabe ist perfekt für das, was ich tun möchte. Ich bin mir jedoch nicht sicher, ob dies nur ein Zufall ist oder nicht. Kann ich mich auf dieses Verhalten verlassen?
Ich verwende GNU findutils 4.4.2. Ich frage mich, ob dieses Verhalten in allen Versionen von gleich ist find
. Und wenn nicht, ist es zumindest für alle Versionen von GNU find gleich.
Es ist mir (für diesen Anwendungsfall) egal, ob Jen im ersten Beispiel gedruckt wird oder nicht . Ich frage mich nur , wenn ich hängen auf sie ausgeschlossen werden , wenn -depth
verwendet wird. Normalerweise ist es keine gute Idee, sich auf undokumentiertes Verhalten zu verlassen. Aber für mich macht dieser Nebeneffekt Sinn. Ich denke also, dass dies das beabsichtigte Verhalten sein könnte.
Das Handbuch sagt:
- Option: -tiefe
Verarbeiten Sie den Inhalt jedes Verzeichnisses vor dem Verzeichnis selbst.
Dies ist genau das , was ich möchte, aber es ist nicht klar, dass der Pfadname des Verzeichnisses selbst von der Ausgabe ausgeschlossen wird, wenn es nicht in das Verzeichnis absteigt.
Dank eines Hinweises von Hauke Laging habe ich festgestellt, dass ich nur Verzeichnisse auflisten und Verzeichnisse explizit ausschließen kann, bei denen die Berechtigung zum Auflisten ihres Inhalts verweigert wird:
find -type d \( \( -type d \( \! -executable -or \! -readable \) \) -prune -or -print \)
Dies hat auch den Effekt, dass die Fehler "Berechtigung verweigert" gestoppt werden, da find
niemals versucht wird, in ein Verzeichnis abzusteigen, wenn es keine Berechtigung hat.
Leider gibt es zwei Gründe, warum dies für meine Bedürfnisse nicht funktioniert.
- Ich möchte die Fehlermeldungen
- Ich brauche die
-depth
Option
Zitat aus dem Handbuch
Wenn die Option '-depth' aktiviert ist, wurden die Unterverzeichnisse in jedem Fall bereits besucht. Daher hat '-prune' in diesem Fall keine Wirkung.
Also bin ich wieder da, wo ich angefangen habe.
Es ist immer noch nicht klar, ob "den Inhalt jedes Verzeichnisses vor dem Verzeichnis selbst verarbeitet" oder nicht. bedeutet auch "Verarbeiten Sie das Verzeichnis nicht, wenn Sie den Inhalt nicht verarbeiten können".
quelle
find
möchten Sie berücksichtigen? Unter Solaris 10,find . -type d
druckt"."
nach stdout und"find: cannot read dir ./jen: Permission denied"
stderr.find . -depth -type d
druckt"find: cannot read dir ./jen: Permission denied"
nach stderr und"."
nach stdout. Weder"./jen"
auf Standard drucken ..
war ein Fehler beim Kopieren und Einfügen. Ich habe meine Frage mit Details zu Versionen und den Details, auf die ich mich verlassen kann, aktualisiert../jen
für drucktfind . -type d
. Es ist immer noch Teil des Inhalts von.
, obwohlfind
es nicht darin absteigen kann. Auf was erweitert sich das./*
Glob-Muster unter Solaris 10? Beinhaltet es./jen
?echo ./*
Ausgänge./jen
. Ich habe die Verzeichnisstruktur so eingerichtet, dass sie mit der des OP übereinstimmt.truss
zeigt , dassfind
tutfchdir()
zum offenen"."
fd, danngetdents64() = 72
,lstat64("jen",...) = 0
,openat(..., "jen", ...) => EACCES
, gibt es dann die Fehlermeldung, danngetdents64() = 0
, dann cleanup und beenden. Dies ist auf der neuesten kostenlosen Solaris 10 / x86-Distribution von Oracle, Generic_147148-26, in einer UFS-PartitionAntworten:
Wahrscheinlich ist der bessere Ansatz, solche Verzeichnisse explizit zu behandeln. Ich weiß nicht, ob dies Standardfunktionen sind, aber zumindest mit Gnu ist
find
dies möglich:Natürlich ist es auch möglich, eine Nachricht zu drucken, wenn ein Verzeichnis ignoriert wird:
quelle
-or print
werden alle Dateitypen gedruckt. Ich möchte nur Verzeichnisse.-print
(dh der Teil nach dem-or
) nur ein Dummy ist, der durch alles ersetzt werden muss, was Sie wollen. ZB können Sie das ändern in-or -type d
.-print
nach dem-or -type d
wichtig ist. Sie können nicht nur ersetzen ,-or -print
mit-or type d
wie im Kommentar vorgeschlagen. Da dies-prune
jedoch keine Auswirkung hat, wenn-depth
es verwendet wird, kehre ich zu meiner ursprünglichen Frage zurück.-printf
Teil nach Ihren Wünschen anpassen . Natürlich können Sie eine Zeile mit dem Pfad und eine andere mit der Fehlermeldung drucken.-print
wird nach dem-or
nur benötigt, wenn im ersten Teil ein Druckbefehl auftritt. Sie brauchen nicht-prune
(ein Absteigen in diese Verzeichnisse ist sowieso unmöglich), damit Sie esdepth
problemlos verwenden können.