Frage Wie beherrsche ich den Befehl UNIX find?


Ich denke, ich bin ziemlich fortgeschritten in meiner Verwendung von finden, aber jedes Mal, wenn ich es benutze, kann ich nicht für das Leben von mir an die Methode erinnern, die Option -exec zu schließen. Ich verbringe viel Zeit damit, jedes Mal zu lesen, wenn ich es benutze. Benütze ich es einfach nicht genug oder erwarte zu viel von mir selbst? Beginnen wir mit einem typischen Beispiel, das mich frustriert.

Die Verzeichnisstruktur hat Dateien mit allen falschen Berechtigungen, versteckte Dateien, symbolische Links usw. Ich möchte den Besitz auf einen vernünftigen Wert ändern

find . -type f -exec chown username {} \;
find . -type d -exec chown username {} \;
find . -type d -exec chgrp usergroup {} \;
find . -type f -exec chgrp usergroup {} \;

(Verzeih mir, wenn das Ende rückwärts ist ... Ich habe es vor einer Stunde angeschaut und bin mir immer noch nicht sicher)

Aber ich habe Angst, es wegen Mounts, symbolischen Verbindungen usw. zu machen. Ich habe das ultimative Chaos von chmod gemacht. Ich weiß, dass xdev auf das Überqueren von Partitionen verzichten wird, aber ich bin mir nicht sicher, was mit den Dateien passieren wird, die in Verzeichnissen leben, die symbolische Links sind.

Wie kann man dieses Biest meistern, das wichtige Dateien töten kann?

Aktualisieren Schneiden Sie die besten Vorschläge unten zusammen und fassen Sie zusammen:

  1. Habe ein Übungsverzeichnis, das mit anderen Übungsverzeichnissen verknüpft und eingebunden ist.
  2. Verwenden Sie lieber xargs als den nicht intuitiven Befehl exec.
  3. Verwenden Sie -exec echo {} für Gesundheit und Sicherheit
  4. Semikolon ist speziell und du entkommst es daher der Escape Char ist zuerst
  5. Der Befehl -or kann Ihnen dabei helfen, Auswahlkriterien zu kombinieren.

Ich bin etwas verwirrt über den print0, aber xargs war schon immer ein bisschen auf dem nicht auf Anhieb leicht zu verstehenden üben, dass ich versuche und meide.


11
2018-06-22 00:23


Ursprung


Ich kann mich auch nicht daran erinnern, also schicke ich es einfach in Xargs. - resonator
Wenn Sie mit dem Erstellen des richtigen Befehls zufrieden sind, sollten Sie es mit + anstelle von \; Es läuft schneller mit +, weil der Befehl exec viel seltener aufgerufen wird. - wzzrd
wzzrd, großer Tipp über die Verwendung von + anstatt von \; - Daniel Lawson


Antworten:


Nun, soweit das -exec Syntax geht, könnte man wie viele Menschen tun, aufgeben und benutzen xargs:

find . -type f | xargs chown username

(oder die Dateien-mit-Leerzeichen-und-andere-Unsinn-in-ihnen-sichere Version)

find . -type f -print0 | xargs -0 chown username

Oder, um zu versuchen, sich an das richtige Semikolon zu erinnern, was Sie in Ihren Kopf bohren müssen, ist, dass Sie ein Semikolon verwenden kündigen das Kommando das -exec läuft, und Sie müssen Flucht das Semikolon, weil es eine besondere Bedeutung hat bash. Deshalb ist es Backslash-Semikolon. Du scheinst das zu haben {} Substitutionsteil in Ordnung.

Was das Töten von Dateien anbelangt und so weiter, wenn du etwas Großes und Gefährliches ausführst, von dem du sprichst, mach das zuerst:

find . -type f -exec echo chown username {} \;

und überprüfen Sie die Ergebnisse. Dies ist im Grunde ein "Trockenlauf", bei dem Sie die Befehle sehen, die ausgeführt werden, wenn Sie es zulassen. Definitiv eine gute Übung. Wird nicht mit dem helfen .* Problem, aber Sie wissen, dass Sie das jetzt nicht tun. :)


19
2018-06-22 00:37



+! Für das "Echo" -Praxis Trockenlauf. Ich benutze das immer für eine große Veränderung - Steve Folly


Ich bin überrascht, dass noch niemand die folgende Option erwähnt hat:

find . -type f -ok chown username {} \;

Diese Syntax bestätigt den Befehl, bevor er ausgeführt wird. Es funktioniert am besten, wenn Sie erwarten, dass Ihre Übereinstimmung eine relativ kleine Anzahl von Dateien ist, weil sie nach jedem einzelnen fragt.

Einige Antworten erwähnen xargs, aber mit GNU finde das auch unnötig:

find . -type f -exec chown username {} \+

Beachten Sie, dass das + in der Regel nicht maskiert werden muss, aber es ist gut, sich an die Gewohnheit zu machen, dies trotzdem zu tun.


3
2018-06-22 05:20



Kannst du die Natur des Pluszeichens erklären ... was macht es genau? Bearbeitet die Shell sie oder den Befehl? Ich denke, ich werde den Quellcode für gnu-find herunterladen, weil das ein interessantes Thema ist. - ojblass
Find verarbeitet es. Lies den Mann, um mehr über diese Option herauszufinden. - Kamil Kisiel


Dafür ist der Mensch da: Es kann schwierig sein, sich an Dinge zu erinnern, deshalb enthält der Befehl * nix man-Seiten. Sie können den Abschnitt AKTION der Manpage immer für eine Erinnerung an die Syntax überprüfen: man find. Obwohl Manpages vielleicht nicht freundlich erscheinen, sind sie sehr praktisch, wenn man sie einmal gut lesen kann.

Erstellen Sie ein Front-End oder Wrapper: Als ich bei GNU besser werden wollte finde ich einen GUI-Frontend zum Suchen Das generiert Suchbefehle mit Python, Glade und Pygtk. Dies ist eine gute Übung, wenn Sie es wirklich gut kennen lernen möchten.

Habe ein Praxisverzeichnis: Schließlich habe ich immer ein "Schrott" -Verzeichnis in meinem Home-Verzeichnis, um mit mächtigen Befehlen zu spielen, wenn etwas wie "Echo" es nicht schneidet. Sie können die Shell-Erweiterung verwenden, um schnell eine Menge Dateien zu erstellen, die Folgendes enthalten:

for i in {1..100}; do touch "$i"; done

3
2018-06-22 13:26



Seltsam ein Praxisverzeichnis ist etwas, das ich nie in Betracht gezogen habe. - ojblass


Sie können auch Suchausdrücke mit den Operatoren '-und' und '-oder' kombinieren. -und ist implizit:

find . -type f -name "plainfile" ...

ist das gleiche wie

find . -type f -and -name "plainfile" ...

Der Operator oder kann die Liste der 4 Befehle auf 2 reduzieren:

find . -type d -or -type f ...

Und schließlich, nicht verwandt zu finden, aber chown kann auch die Gruppe auch setzen. Wenn wir also auch mit den Namen umgehen, enden wir mit:

find . -type d -or -type f -exec chown username:usergroup '{}' \;

1
2018-06-22 05:29



Was finden Sie mit dem -oder Geschäft. [Sic] - ojblass
@ojblass: find kombiniert Ausdrücke mit 'und' oder 'oder', wenn weder '-und' noch '-oder' angegeben sind, wird '-und' implizit verwendet. Geben Sie also 'find -type d -type f' ein, da nichts ein Verzeichnis ist und eine Datei. - Steve Folly


Beim Schließen denke ich nur daran zu benutzen; wie mit vielen Programmiersprachen und dann entkommen. Denken Sie daran, dass es notwendig ist, entflohen zu sein und es kommt ziemlich leicht zu Ihnen.


0
2018-06-22 01:03





Abhängig von der Version von Find, die Sie verwenden, gibt es verschiedene Optionen, die Ihnen helfen können. GNU find ist wahrscheinlich der mächtigste und das kann dir bei deiner zweiten (implizierten) Frage helfen

Zum Beispiel - das Standardverhalten besteht nicht darin, symbolische Links zu dereferenzieren, aber Sie können dies überschreiben; und die Option -mount stoppt die Suche nach Mountpunkten

Schau in deinen lokalen Manpages nach


0
2018-06-22 01:53





Manche würden streiten dass die Option xargs schneller als die Option -exec ist, weil sie den Befehl nicht für jede Datei einmal ausführt, aber ich würde mir darüber keine Gedanken machen, außer über massive Jobs, die eine nicht unerhebliche Menge an Zeit benötigen.

Persönlich laufe ich normalerweise nur ohne exec

find /path/to/dir -name whatever

Stellen Sie sicher, dass die Ausgabe korrekt aussieht, und führen Sie dann meinen Befehl in dieser Liste aus.

chown user:group `find /path/to/dir -name whatever`

0
2018-06-22 02:19



Perfektes Beispiel dafür, wie man "nicht" Dinge macht. Dateinamen mit Leerzeichen - Ian Kelling
Ja, das ist ein potentielles Problem, das ich vielleicht hätte anerkennen müssen. Allerdings ging es mir darum, die Find-Ausgabe vor dem Ausführen von irgendetwas zu lesen, wo Sie Leerzeichen oder andere Dateinamen-Wahnsinn entdecken würden. - theotherreceive


Für einige Shells (nicht bash) entkomme {} für korrektes Verhalten.

\{\} or '{}'

Handbuch finden ist gut zum Beherrschen finden.


0
2018-06-22 01:57



Nein, tust du nicht; Finden Sie läuft gut mit dem {}, wie sie sind. Sie sind Teil des Befehls find: Sie sind ein Token, das durch das Ergebnis des Befehls find ersetzt wird. Sie bedeuten nur etwas in bash, wenn Sie Funktionen definieren oder Variablen aufrufen. Sie können sie also wie in der ursprünglichen Frage verwenden. - wzzrd
Es ist von der Manpage. Ich habe aktualisiert, um zu sagen, dass es nicht auf bash anwendbar ist. - Ian Kelling


Bevor Sie so etwas tun, stellen Sie sicher, dass das Verzeichnis, in dem dieser Befehl ausgeführt wird, nicht im selben Dateisystem wie / usr oder / etc ist. (Anderenfalls, wenn ich eine feste Verbindung zu / etc / passwd oder zu / bin / sh in meinem Home-Verzeichnis habe, habe ich ihnen das Eigentum gegeben und als Nebeneffekt besitze ich jetzt die Maschine).

Wenn Sie durch ein Verzeichnis recurse und alle Dateien / Verzeichnisse chown, ein einfaches

chown -Rh Benutzer: Benutzergruppenbenutzer /

werde es tun. Machen sicher Sie verwenden die -h oder chown folgen symbolischen Links.


0
2018-06-23 14:57



Ich denke nicht, dass das plattformübergreifend ist. Scheitert auch mit 247K Dateien, wie von meiner Praxisumgebung gezeigt. Ich bin mir nicht sicher warum. - ojblass
Ich denke, Sie haben einen Fehler gefunden, mehr als Sie ein plattformübergreifendes Problem gefunden haben. Welche Version und was ist der Exit-Status, wenn es fehlschlägt? Soweit ich es beurteilen kann, entstand es zuerst in frühen bsd-Versionen; Es ist definitiv in Sonnen 5.3 und Ultrix und Irix. Wie viele verarbeitet es, bevor es fehlschlägt? - chris
Sie haben recht, es funktioniert unter AIX 5.3, AIX 5.2, aber nicht unter AIX 4.3, NCR, HP 11, HP 10.20 oder meinen DSL-Distributionen. In allen Fällen scheint es bei oder in der Nähe von 60k-Dateien zu versagen. - ojblass