trova: argomento mancante per -exec

Oggi sono stato aiutato con un comando, ma non sembra funzionare. Questo è il comando:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\; 

La shell ritorna

 find: missing argument to `-exec' 

Quello che sto praticamente cercando di fare è passare attraverso una directory ricorsivamente (se ha altre directory) ed eseguire il comando ffmpeg sui tipi di file .rm e convertirli in tipi di file .mp3 . Fatto ciò, rimuovere il file .rm appena convertito.

Apprezzo qualsiasi aiuto su questo.

Un comando -exec deve essere terminato con a ; (di solito è necessario digitare \; o ';' per evitare l’interpretazione da parte della 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 diviso) con tutti i nomi di file. Vedi 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 

Il tuo comando ha due errori:

Innanzitutto, usi {}; , ma il ; deve essere un parametro a sé stante.

Secondo, il comando termina con && . Hai specificato “run find” e, se ciò è successo, rimuovi il file chiamato {}; . “. Se si desidera utilizzare la shell roba nel comando -exec , è necessario eseguirla 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, puoi passare parametri aggiuntivi alla 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. Immagina che ci fosse un file chiamato $(rm -rf /) 🙂

(Nota a margine: il - non è necessario, ma la prima variabile dopo che il comando è stato assegnato alla variabile $0 , che è una variabile speciale che normalmente contiene il nome del programma in esecuzione e impostarla su un parametro è un po ‘sporca, sebbene probabilmente non causerà alcun danno qui, quindi lo impostiamo su solo - e iniziamo con $1 )

Quindi il tuo comando potrebbe essere qualcosa di simile

 find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \; 

Ma c’è un modo migliore. trova i supporti and e, quindi, puoi fare cose come find -name foo -or -name bar . Ma funziona anche con -exec , che -exec true se il comando termina correttamente, e false se non lo è. Vedi questo esempio:

 $ ls false true $ find * -exec {} \; -and -print true 

Esegue la stampa solo se il comando è stato eseguito correttamente, cosa che ha fatto per true ma non per false .

Quindi puoi usare due istruzioni exec concatenate con un -and , ed eseguirà quest’ultimo solo se il primo è stato eseguito con successo.

L’ho capito ora. Quando hai bisogno di eseguire due comandi in exec in un find hai bisogno di avere due exec separati. Questo alla fine ha funzionato per me.

 find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \; 

Prova a mettere uno spazio prima di ogni \;

Lavori:

 find . -name "*.log" -exec echo {} \; 

Non funziona:

 find . -name "*.log" -exec echo {}\; 

Solo per tua informazione:
Ho appena provato a usare il comando “find -exec” su un sistema Cygwin (UNIX emulato su Windows), e sembra che sia stata rimossa la barra rovesciata prima della virgola:
find ./ -name "blabla" -exec wc -l {} ;

Nel caso qualcuno vedesse un simile “missing-esec args” negli script di Amazon Opsworks Chef, avevo bisogno di aggiungere un altro backslash per uscire da \;

 bash 'remove_wars' do user 'ubuntu' cwd '/' code <<-EOH find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\; EOH ignore_failure true end 

Inoltre, se qualcun altro ha il “find: missing argument to -exec” questo potrebbe aiutare:

In alcune shell non è necessario eseguire l’escaping, ovvero non è necessario il segno “\” davanti a “;”.

 find  -name "myFile.*" -exec rm - f {} ; 

Devi fare un po ‘di fuga, penso.

 find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} \-sameq {}.mp3 \&\& rm {}\; 

Sia {} che && causeranno problemi dovuti all’espansione dalla riga di comando. Suggerirei di provare:

 find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \; 

Se stai ancora ottenendo “find: missing argument to -exec” prova a racchiudere l’argomento execute tra virgolette.

 find  -type f -exec "chmod 664 {} \;"