- "Ovviamente"
-exec …
deve essere terminato con un punto e virgola ( ;
) o un segno più ( +
). Punto e virgola è un carattere speciale nella shell (o, almeno, ogni shell che abbia mai usato), quindi, se è per essere utilizzato come parte del find
comando , deve essere sfuggito o citato ( \;
, ";"
, o ';'
).
Con -exec … ;
, la {}
stringa può apparire un numero qualsiasi di volte nel comando, incluso zero , o due o più, in qualsiasi posizione.
Vedi questo
per un esempio del perché potresti voler fare a -exec
meno di usare {}
.
Avere due o più apparizioni è utile principalmente perché, in (almeno) alcune versioni di find
, {}
non è necessario che sia una parola da sola; può avere altri personaggi all'inizio o alla fine; per esempio,
find . -type f -exec mv {} {}.bak ";"
Con -exec … +
, la {}
stringa deve apparire come ultimo argomento prima del +
. Un comando simile
find . -name "*.bak" -exec mv {} backup_folder +
provoca il find: missing argument to ‘-exec’
messaggio enigmatico di errore.
Una soluzione alternativa per questo che è specifica per i comandi cp
e mv
è
find . -name "*.bak" -exec mv -t backup_folder {} +
o
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
La {}
deve essere una parola di per sé; non può avere altri personaggi all'inizio o alla fine. E, in (almeno) alcune versioni di find
, potresti non averne più di una {}
.
Una nota di sanità mentale: puoi dire
trova . -name "* .sh" -type f -executable -exec {} args opzionale qui ";"
per eseguire ciascuno dei tuoi script. Ma
trova . -name "* .sh" -type f -executable -exec {} +
esegue uno dei tuoi script, con i nomi di tutti gli altri come parametri. Questo è simile al dire
./*.sh
come comando shell, tranne find
che non garantisce che ordina i suoi risultati, quindi non sei garantito per l'esecuzione aaa.sh
(il tuo primo *.sh
file in ordine alfabetico ) come saresti con l'esecuzione ./*.sh
.
Un aspetto find
che potrebbe non essere perfettamente chiaro ai principianti è che la riga di comando è, in effetti, un'istruzione eseguibile in un linguaggio arcano. Per esempio,
find . -name "*.sh" -type f -executable -print
si intende
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
o, semplicemente,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Alcune delle -
parole chiave sono sia un'azione eseguibile che un test. In particolare, questo è vero per -exec … ;
; per esempio,
find . -type f -exec grep -q cat {} ";" -print
si traduce in
per ogni file
se è un file semplice (cioè non una directory)
poi
esegue grep -q cat nomefile
se il processo ha esito positivo (ovvero, esce con stato 0)
poi
stampa il nome del file
finisci se
finisci se
end loop
che stamperà i nomi di tutti i file contenenti la stringa “ cat
”. E, mentre questo è qualcosa che grep
può fare da solo (con l' opzione -l
(lettere minuscole L
), può essere utile usarlo con find
per trovare file che contengono una determinata stringa E hanno una certa dimensione E sono di proprietà di un determinato proprietario E sono stati modificati in un determinato intervallo di tempo, ....
Tuttavia, questo non funziona per -exec … +
. Poiché -exec … +
esegue un comando per più file, non ha senso usarlo come condizione logica all'interno di un for each file …
ciclo.
- Il rovescio della medaglia di quanto sopra è che
find
generalmente esce con uno stato di uscita pari a 0 a meno che non gli dia argomenti non validi o incontri una directory che non può leggere. Anche se un programma che si esegue ha esito negativo (esce con uno stato di uscita diverso da zero),
find
uscirà con uno stato di uscita pari a 0.
Tranne se un programma che si esegue con -exec … +
esito negativo (esce con uno stato di uscita diverso da zero),
find
uscirà con uno stato di uscita diverso da zero.
... -exec mv {} {}.bak ...
non è garantito per funzionare come previsto con tutte lefind
implementazioni. Gli stati standard POSIX{}
devono apparire da soli per essere sempre riconosciuti, altrimenti il comportamento è libero di mantenere invariati i caratteri o di sostituirli con il nome del percorso. Nel primo caso, l'intero comando eliminerà essenzialmente tutti i file ma l'ultimo trovato ...