Un comando -exec
deve essere terminata con un ;
(modo che di solito bisogno di digitare \;
o ';'
per evitare interpretion dalla shell) o un +
. La differenza è che con ;
, il comando viene chiamato una volta per file, con +
, viene chiamato solo poche volte (solitamente una volta, ma c'è una lunghezza massima per una riga di comando, quindi potrebbe essere suddiviso) con tutti i nomi di file. Vedere questo esempio:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
tuo comando ha due errori:
In primo luogo, si utilizza {};
, ma il ;
necessario essere un parametro a sé stante.
In secondo luogo, il comando termina allo &&
. Hai specificato "Esegui ricerca e, se ciò è successo, rimuovi il file denominato {};
". Se si desidera utilizzare la shell nel comando -exec
, è necessario eseguirlo esplicitamente in una shell, ad esempio -exec sh -c 'ffmpeg ... && rm'
.
Tuttavia, non si dovrebbe aggiungere {} all'interno del comando bash, questo produrrà problemi quando ci sono caratteri speciali. Invece, è possibile passare parametri aggiuntivi per la shell dopo -c command_string
(vedi man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Vedete la cosa $
viene valutata dalla shell nel primo esempio.Immaginate c'era un file chiamato $(rm -rf /)
:-)
(Nota a margine: Il -
non è necessaria, ma la prima variabile dopo il comando viene assegnato alla variabile $0
, che è una variabile speciale normalmente contiene il nome del programma in esecuzione e l'impostazione che a un parametro è un po 'sporca, ma non causerà alcun danno qui, probabilmente, così abbiamo deciso che a poco -
e iniziare con $1
.)
così il vostro comando potrebbe essere qualcosa di simile
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Ma c'è un modo migliore. trovare supporta and
e or
, quindi è possibile fare cose come find -name foo -or -name bar
. Ma funziona anche con -exec
, che restituisce true se il comando termina correttamente e false se non lo è. Vedere questo esempio:
$ ls
false true
$ find * -exec {} \; -and -print
true
funziona solo la stampa se il comando fosse successo, che ha fatto per true
ma non per false
.
Quindi è possibile utilizzare due istruzioni exec concatenate con uno -and
e verrà eseguito solo quest'ultimo se il primo è stato eseguito correttamente.
Non si sa se otterrà la variabile del file da eliminare? Qualcuno sa se questo è il caso? – Abs
Per testare queste cose basta aggiungere un 'echo' prima dei comandi e vedere cosa fa. – Marian