Hilfe zum Verständnis der `find`-Syntax unter Solaris

Hilfe zum Verständnis der `find`-Syntax unter Solaris

Betrachten Sie die folgenden Dateien:

$ find findtest                     
findtest
findtest/test1
findtest/test1/start.ksh
findtest/test2
findtest/test2/start.ksh
findtest/test3
findtest/test3/start.ksh
findtest/test4
findtest/test4/start.ksh

Meine Frage bezieht sich auf die Verwendung von {}im -execAufruf. Es funktioniert so, wie ich es bei der Bezeichnung der Ergebnisdatei erwarten würde:

$ find findtest -name test[1-4] -exec ls -d {} \;           
findtest/test1
findtest/test2
findtest/test3
findtest/test4

Allerdings scheint es nicht erweitert zu werden, wenn es in einem Pfad verwendet wird:

$ find findtest -name test[1-4] -exec md5sum {}/start.ksh \;     
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory
md5sum: {}/start.ksh: No such file or directory

Wie kann ich find -type d -execauf Dateien in niedrigerer Hierarchie zugreifen? Ich weiß, dass ich eine forSchleife wie diese verwenden kann, aber ich bin neugierig, ob dies in einem findAufruf möglich ist:

$ for f in $(find findtest -name test[1-4]); do md5sum "$f"/start.ksh; done
d41d8cd98f00b204e9800998ecf8427e  findtest/test1/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test2/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test3/start.ksh
d41d8cd98f00b204e9800998ecf8427e  findtest/test4/start.ksh

Antwort1

DerPOSIX-Standard für den Find-Befehlerfordert nur das Ersetzen eines isolierten {} durch den Dateinamen und nur des ersten. Die Verwendung {}/start.kshführt zu nicht spezifiziertem Verhalten.

Ein Argument, das nur die beiden Zeichen "{}" enthält, wird durch die Gruppe der zusammengefassten Pfadnamen ersetzt, wobei jeder Pfadname als separates Argument an das aufgerufene Dienstprogramm in derselben Reihenfolge übergeben wird, in der er zusammengefasst wurde. Die Größe einer Gruppe von zwei oder mehr Pfadnamen muss so begrenzt sein, dass die Ausführung des Dienstprogramms nicht dazu führt, dass das {ARG_MAX}-Limit des Systems überschritten wird. Wenn mehr als ein Argument vorhanden ist, das nur die beiden Zeichen "{}" enthält, ist das Verhalten nicht spezifiziert.

Wenn ein Utility-Name oder eine Argumentzeichenfolge die beiden Zeichen „{}“, aber nicht nur die beiden Zeichen „{}“ enthält, ist es implementierungsdefiniert, ob find diese beiden Zeichen ersetzt oder die Zeichenfolge unverändert verwendet.

Eine Möglichkeit, mit Solaris find das gewünschte Ergebnis zu erzielen, wäre dieser Befehl:

find findtest -name "test[1-4]" -exec sh -c 'md5sum $1/start.ksh' foo {} \;

Ein schnellerer Weg wäre:

find findtest -name "test[1-4]" -exec sh -c 'for i; do md5sum "$i/start.ksh"; done' foo {} + 

Antwort2

  1. Tatsächlich wird Ihre Shell erweitert, test[1-4]bevor sie aufruft find. Sie müssen sie mit verlassen'…'
  2. {}wird nur dann als Muster behandelt, wenn es sich um ein separates Token handelt

-execselbst ist normalerweise kostspielig und sollte entweder in Verbindung mit Schleppnetzen verwendet +oder zugunsten der Fütterung vermieden werden xargs.

Ich weiß, dass ich eine For-Schleife wie diese verwenden kann, aber ich bin neugierig, ob dies mit einem einzigen Find-Aufruf möglich ist:

find findtest -name 'test[1-4]' -print0 | xargs -0I{} -- md5sum '{}/start.ksh'— läuft md5sumeffizient — mit der gleichzeitigen Angabe aller Dateinamen.

verwandte Informationen