Warum muss 'find -exec cmd {} +' mit '{} +' enden?

11

Vorwort: Ich verstehe den Unterschied zwischen -exec {} \;& -exec {} +. Ich habe auch kein Problem als solches , ich bin nur neugierig auf die Semantik von find.


Wenn das Ende -execmit dem Argumente +statt ;, wir müssen dazu am Ende mit {} +, zum Beispiel:

# FreeBSD find
$ find . -type f -exec cp {} /tmp +
find: -exec: no terminating ";" or "+"

# GNU find is even more cryptic:
$ find: missing argument to `-exec'

Die Verwendung ;in diesen Beispielen anstelle von +funktioniert gut (macht aber offensichtlich etwas anderes).

Von POSIX :

-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +

... Nur ein <plus-sign>, das unmittelbar auf ein Argument folgt, das nur die beiden Zeichen " {}" enthält, darf das Ende des primären Ausdrucks markieren. Andere Verwendungen des <plus-sign> werden nicht als besonders behandelt.

Mit anderen Worten, wenn die Verwendung +der Befehl muss mit beenden {} +.

Warum ist das? Und warum nur mit dem +und nicht mit dem ;? Zuerst dachte ich, vielleicht um Konflikte mit Dateinamen zu vermeiden, die ein enthalten +, aber Dateinamen mit einem ;scheinen gut zu funktionieren? Es fällt mir schwer zu glauben, dass diese Einschränkung willkürlich ist ...

Martin Tournoij
quelle
3
FWIW, die POSIX-Seite sagt auch, dass The "-exec ... {} +" syntax adopted was a result of IEEE PASC Interpretation 1003.2 #210und in diesem Dokument finden Sie weitere Details, zB:Note that the "+" is only treated as special if it immediately follows "{}". This minimises the chances of causing problems with existing uses of "+" as an argument with "-exec".
don_crissti

Antworten:

5

Die in der POSIX-Spezifikation angegebene Begründung lautet:

Die verwendete "-exec ... {} +"Syntax war ein Ergebnis der IEEE PASC Interpretation 1003.2 # 210. Es ist zu beachten, dass dies eine inkompatible Änderung der Norm ISO / IEC 9899: 1999 ist. Der folgende Befehl druckt beispielsweise alle Dateien mit einem '-'Nachnamen, wenn es sich um reguläre Dateien handelt, und einem '+'anderen:

find / -type f -exec echo {} - ';' -o -exec echo {} + ';'

Die Änderung macht die Verwendung wie folgt ungültig. Obwohl der vorherige Standard besagte, dass diese Verwendung funktionieren würde, wurde sie in der Praxis von vielen nicht unterstützt, und die Standardentwickler hielten es für besser, jetzt anzugeben, dass dies nicht zulässig war.

PASC Interpretation 1003.2 # 210 geht detaillierter auf die Geschichte von -exec … {} +. Es existierte auf mehreren Unix-Systemen, bevor es von POSIX übernommen wurde. Der Fehlerbericht führt es auf SVR4 zurück (wo es weitgehend undokumentiert war). Der Fehlerbericht rechtfertigt die inkompatible Änderung als wenig wirkungsvoll in der Praxis:

Beachten Sie, dass das "+" nur dann als besonders behandelt wird, wenn es unmittelbar auf "{}" folgt. Dies minimiert die Wahrscheinlichkeit, Probleme mit vorhandenen Verwendungen von "+" als Argument mit "-exec" zu verursachen.

Obwohl das Hinzufügen von Unterstützung für -exec … {} +einige konforme Anwendungen wie das obige Beispiel beschädigt würde, gibt es weniger davon, als wenn dies -exec … {} … +zulässig wäre.

Ein weiterer Grund, sich vielleicht darauf zu beschränken {}, das letzte Argument zu sein, ist die einfache Implementierung. Wenn dies {}irgendwo in der Argumentliste erlaubt wäre -exec, findmüsste das Programm die Befehlszeile erstellen, indem es die statischen Argumente, dann den variablen Teil und dann einen anderen statischen Teil kopiert. Dies würde es schwieriger machen, die Argumentliste zu erstellen und die Größenbeschränkung zu berücksichtigen. Die Schwierigkeit ist minimal, aber Implementierer schneiden gerne Ecken. Die Unterstützung mehrerer austauschbarer Instanzen von {}(wenn dies -exec {} foo +funktionieren soll, kann dies logischerweise auch erwartet werden -exec {} foo {} +) wäre erheblich schwieriger.

Gilles 'SO - hör auf böse zu sein'
quelle