Ich verstehe, dass die -exec eine + -Option annehmen kann um das Verhalten von xargs nachzuahmen. Gibt es eine Situation, in der Sie „ein Formular dem anderen vorziehen würden?

Ich persönlich bevorzuge das erste Formular, wenn auch nur, um die Verwendung einer Pipe zu vermeiden. Ich denke, die Entwickler von find muss die entsprechenden Optimierungen vorgenommen haben. Bin ich richtig?

Antwort

Möglicherweise möchten Sie Anrufe verketten, um zu finden (einmal, als Sie erfahren haben, dass dies möglich ist , was heute sein könnte). Dies ist natürlich nur möglich, solange Sie in find bleiben. Sobald Sie zu xargs weitergeleitet haben, liegt der Gültigkeitsbereich außerhalb des Bereichs.

Kleines Beispiel, zwei Dateien a.lst und b.lst:

cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh 

Kein Trick hier – einfach die Tatsache, dass beide „Fuddel“ enthalten, aber nur einer „Fiddel“.

Angenommen, wir wussten das nicht. Wir suchen eine Datei, die zwei Bedingungen entspricht:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls 192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst 

Nun, vielleicht kennen Sie die Syntax für grep oder ein anderes Programm, um beide Zeichenfolgen als Bedingung zu übergeben, aber das “ Hier kann jedes Programm verwendet werden, das mit einer Datei als Argument true oder false zurückgeben kann – grep war nur ein beliebtes Beispiel.

Und beachten Sie, dass Sie find -exec mit anderen Suchbefehlen wie -ls oder -delete oder ähnliches. Beachten Sie, dass beim Löschen nicht nur rm (Dateien entfernt), sondern auch rmdir ausgeführt wird (entfernt Verzeichnisse) auch.

Eine solche Kette wird als UND-Kombination von Befehlen gelesen, sofern nicht anders angegeben (nämlich mit einem -or -Schalter (und) parens (die maskiert werden müssen)).

Sie verlassen also nicht die Suchkette, was praktisch ist. Ich sehe keinen Vorteil in der Verwendung von -xargs, da Sie beim Übergeben der Dateien vorsichtig sein müssen, was bei find nicht erforderlich ist – es behandelt automatisch das Übergeben jeder Datei als einzelnes Argument für Sie.

Wenn Sie glauben, dass Sie eine Maskierung für Fundstücke benötigen, {} Klammern , können Sie meine Frage besuchen, in der nach Beweisen gefragt wird. Meine Behauptung lautet: Sie tun es nicht.

Kommentare

  • Dieser Beitrag hat mir die Augen für eine neue Art der Verwendung von . Vielen Dank!
  • “ Ich sehe ‚ keinen Vorteil bei der Verwendung -xargs „. Was ‚ ist die -exec Vorgehensweise xargs -P4, damit drei von vier Kernen nicht ‚ untätig bleiben?
  • @DamianYerrick: Beenden Sie den Befehl -exec nicht in „; „, jedoch mit einem + (/ Pluszeichen).

Antwort

Um Dateinamen sicher an xargs weiterzuleiten, muss Ihre find die -print0 Option und Ihre xargs hat die entsprechende Option zum Lesen (--null oder -0). Andernfalls Dateinamen mit unprintab Die Zeichen oder Backslashes oder Anführungszeichen oder Leerzeichen im Namen können zu unerwartetem Verhalten führen. Andererseits befindet sich find -exec {} + in der POSIX find -Spezifikation Es ist also portabel und ungefähr so sicher wie find -print0 | xargs -0 und definitiv sicherer als find | xargs. Ich würde empfehlen, niemals find | xargs ohne -print0 auszuführen.

Kommentare

  • Eine bemerkenswerte Ausnahme von der Portabilität von find … -exec … {} + ist OpenBSD, das diese Funktion erst mit der 2012 veröffentlichten Version 5.1 erworben hat. Alle BSDs hatten -print0 für mehrere Jahre, sogar OpenBSD (obwohl es dieser Funktion auch eine Weile widerstand). Solaris hingegen hält sich an POSIX-Funktionen, sodass Sie und nein -print0.
  • -print0 ist ein Schmerz und obwohl Sie argumentieren können xargs --delimiter "\n" ist nicht ‚ t äquivalent, ich ‚ habe das erstere noch nie verwendet, nachdem ich das letztere entdeckt habe
  • Ich sehe ‚ nicht, wie -0 mehr Schmerzen verursacht als --delimiter "\n".
  • Zusätzlich zu -0, GNU xargs benötigt -r, um die Ausführung des Befehls zu vermeiden, wenn ‚ keine Eingabe erfolgt.
  • Ein weiteres Problem von | xargs -r0 cmd ist, dass cmd ‚ s stdin ist betroffen (abhängig von der Implementierung von xargs ist ‚ s /dev/null oder der Pipe.

Antwort

Wenn Sie das Formular -exec ... ; verwenden (merken) Um dem Semikolon zu entkommen, führen Sie den Befehl einmal pro Dateiname aus. Wenn Sie -print0 | xargs -0 verwenden, führen Sie mehrere Befehle pro Dateiname aus. Sie sollten auf jeden Fall die -Formular, das mehrere Dateien in einer einzigen Befehlszeile platziert und viel schneller ist, wenn eine große Anzahl von Dateien beteiligt ist.

Ein großes Plus bei der Verwendung von xargs ist die Möglichkeit, mehrere Befehle mit xargs -P parallel auszuführen. Auf Mehrkernsystemen kann dies eine enorme Zeitersparnis bedeuten.

Kommentare

  • Sie meinten -P anstelle von -p. Beachten Sie, dass xargs -P nicht im POSIX-Standard enthalten ist, während find -exec {} + wichtig ist, wenn Sie Portabilität anstreben.
  • @Alexios Sie müssen ‚ nicht dem Pluszeichen entkommen, da es für die Shell keine besondere Bedeutung hat: find /tmp/ -exec ls "{}" + funktioniert einwandfrei.
  • Corrent natürlich. Ich ‚ habe so lange nach dem -exec alles entkommen (I ‚ ma masochist Ich verwende ‚ nicht einmal Anführungszeichen, um {} zu entkommen. Ich gebe immer \{\} ein. ‚ nicht fragen), alles sieht so aus, als müsste es jetzt entkommen.
  • @Alexios: Wenn Sie ein Beispiel finden (außer als Masochist), wo die Das Maskieren der Klammern ist nützlich, bitte geben Sie es als Antwort auf meine Frage hier – afaik dieser Hinweis ist veraltet und nur ein Relikt in der Manpage. Ich ‚ habe noch nie ein Beispiel gesehen, bei dem find /tmp/ -exec ls {} + ‚ nicht funktioniert.
  • Für mich ist dies das Muskelgedächtnis, das in den Tagen von SunOS 4 gebildet wurde. Da ich ‚ es seit Jahren mache, habe ich es völlig versäumt zu bemerken, wann bash akzeptierte die geschweiften Klammern wörtlich. Ich ‚ bin mir ziemlich sicher, dass mindestens eine der alten Muscheln, die ich ‚ verwendet habe, zischende Anfälle verursachte, wenn die Zahnspangen nicht ‚ ist nicht entkommen.

Antwort

In Bezug auf die Leistung dachte ich, dass -exec … + wäre einfach besser, weil es „ein einziges Tool ist, das die ganze Arbeit erledigt, aber ein Teil der Dokumentation von GNU findutil besagt, dass -exec … + ist in einigen Fällen möglicherweise weniger effizient:

[find with -exec … +] kann weniger effizient sein als einige Verwendungen von xargs; Mit xargs können beispielsweise neue Befehlszeilen erstellt werden, während der vorherige Befehl noch ausgeführt wird, und Sie können eine Reihe von Befehlen angeben, die parallel ausgeführt werden sollen. Das Konstrukt find ... -exec ... + bietet jedoch den Vorteil einer breiten Portabilität. GNU findutils unterstützten „-exec ... +“ erst in Version 4.2.12 [Januar 2005] ; Einer der Gründe dafür ist, dass es auf jeden Fall bereits die Aktion „-print0“ gab.

Ich war mir nicht sicher, was das bedeutete, also fragte ich im Chat, wo derobert erklärte es als:

find könnte wahrscheinlich weiterhin nach dem nächsten Stapel von Dateien suchen, während die -exec … + wird ausgeführt, aber nicht.
find … | xargs … wird ausgeführt, da die Suche dann ein anderer Prozess ist und beibehalten wird Wird ausgeführt, bis der Pipe-Puffer voll ist.

(Formatierung durch mich.)

Das gibt es also. Aber wenn Leistung wirklich wichtig ist, müssten Sie ein realistisches Benchmarking durchführen oder sich sogar fragen, ob Sie in solchen Fällen überhaupt Shell verwenden möchten.

Hier auf dieser Website ist es meiner Meinung nach besser, die Leute zu beraten Verwenden Sie nach Möglichkeit das Formular -exec … +, nur weil es einfacher ist und aus den in den anderen Antworten hier genannten Gründen (z. B. Umgang mit seltsamen Dateinamen, ohne viel nachdenken zu müssen).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.