tl;dr:-delete
není vyžadováno POSIX, -exec
je.
Fakta
Manuálová stránka POSIX 1003.1 pro find
určuje -exec
ale ne -delete
.
To znamená -exec
by měl fungovat prakticky všude. Překvapilo by mě nalezení find
který má -delete
bez -exec
. Opak je docela možný. Zvláště lehké systémy, které používají busybox
mají tendenci poskytovat pouze základní možnosti příkazového řádku.
Např. Na jednom ze svých routerů mám OpenWRT a jeho find
rozumí -exec
, nerozumí -delete
.
Nemáte -delete
není velký problém, když máte -exec rm …
. Na druhou stranu -delete
nelze nahradit -exec
obecně. Je to moudrý návrh, který umožňuje vynechat -delete
první.
Osobní zkušenosti, postřehy a názory
Výše uvedené by mělo být hlavním důvodem, proč -exec rm {} \;
se tak široce doporučuje. Sekundární může být efekt sněhové koule. Uživatelé čtou články a příklady, seznamují se s -exec
a publikovat své vlastní příkazy (např. zde na Super User). Někteří z nich možná ani neznají -delete
existuje.
Několikrát jsem viděl (nebo dal) poznámky jako „Můžete použít -delete
namísto'. A odpovědi byly jako 'Díky, to jsem nevěděl'. Nepamatuji si žádnou odpověď 'Já vím, ale tohle není POSIX'.
Po tom všem mám tendenci zmiňovat -delete
kdykoli -exec rm {} \;
objeví se. Důvod je -delete
nevytváří nový proces, zatímco -exec rm {} \;
vyvolá samostatný rm
pro každý odpovídající soubor. Pokud nemůžete použít -delete
pak by vaše další myšlenka měla být -exec rm {} +
který dokáže odstranit více souborů jediným rm
(stále bude volat rm
v případě potřeby více než jednou).
Proč není -exec … +
široce doporučeno? Může to být kvůli jeho omezením. Umím si představit nezkušeného uživatele, který si myslí:'Tohle funguje s rm
, dovolte mi jej použít s mv
' Potom -exec mv {} foo/ +
nefunguje, protože {}
musí být na konci, těsně před +
. Uživatel je frustrovaný a běží zpět k mámě Windows.
Doporučuji -delete
Myslím, že je zde na Super User obvykle v bezpečí. Většina otázek uvádí "velké" OS, find
příkazy jsou bohaté na možnosti. A to i v případě, že existuje uživatel, jehož find
je omezená, pravděpodobně dostanu zpětnou vazbu. Říká, že pro ně řešení nefunguje, a já navrhuji -exec rm …
místo toho vysvětlete problém atd.
Samostatný článek, který doporučuje -delete
takovou zpětnou vazbu nedostane. V případě jakýchkoli potíží uživatel jednoduše přejde na další odkaz vrácený společností Google.
Rozdíl je ve flexibilitě. Pokud použijete -exec, provedete příkaz pro každý vybraný soubor. Pokud použijete -exec, můžete flexibilně použít další možnosti hledání. S -delete jste omezeni v použití -prune. Kromě toho vaše umístění -delete ovlivňuje vaše výsledky. Viz úryvek dokumentace níže:
-delete
Delete files; true if removal succeeded. If the removal failed,
an error message is issued. If -delete fails, find’s exit status will be
nonzero (when it eventually exits). Use of -delete automatically turns on
the ‘-depth’ option.
Warnings: Don’t forget that the find command line is evaluated as an
expression, so putting -delete first will make find try to delete every-
thing below the starting points you specified. When testing a find
command line that you later intend to use with -delete, you should
explicitly specify -depth in order to avoid later surprises.
Because -delete implies -depth, you cannot usefully use -prune and -delete
together.
-exec command ;
Execute command; true if 0 status is returned. All following arguments
to find are taken to be arguments to the command until an argument
consisting of ‘;’ is encountered. The string ‘{}’ is replaced by the
current file name being processed everywhere it occurs in the arguments
to the command, not just in arguments where it is alone, as in
some versions of find. Both of these constructions might need to be escaped
(with a ‘\’) or quoted to protect them from expansion by the shell.
See the EXAMPLES section for examples of the use of the -exec option.
The specified command is run once for each matched file. The
command is executed in the starting directory. There are unavoidable security
problems surrounding use of the -exec action; you should use the -execdir
option instead.
-exec command {} +
This variant of the -exec action runs the specified command on the
selected files, but the command line is built by appending each selected
file name at the end; the total number of invocations of the command
will be much less than the number of matched files. The command line is
built in much the same way that xargs builds its command lines.
Only one instance of ‘{}’ is allowed within the command. The command is
executed in the starting directory