2010-06-02 51 views
153

Me ayudaron hoy con un comando, pero parece que no funciona. Este es el comando:encontrar: falta el argumento para -exec

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

La cáscara vuelve

find: missing argument to `-exec' 

Lo que básicamente estoy tratando de hacer es ir a través de un directorio de forma recursiva (si tiene otros directorios) y ejecute el comando ffmpeg en el .rm tipos de archivos y convertirlos a .mp3 tipos de archivos. Una vez hecho esto, elimine el archivo .rm que acaba de convertir.

Agradezco cualquier ayuda en esto.

Respuesta

45

Lo descubrí ahora. Cuando necesite ejecutar dos comandos en el ejecutivo en un hallazgo, necesita tener dos ejecutivos independientes. Esto finalmente funcionó para mí.

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

¿No está seguro de si eliminará la variable del archivo? Alguien sabe si este es el caso? – Abs

+4

Para probar tales cosas simplemente agregue un 'echo' antes de los comandos y vea lo que hace. – Marian

1

Tienes que escaparte, creo.

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

Tanto {} y & & causará problemas debido a ser expandido en la línea de comandos. Sugeriría probar:

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

Si el primer comando en Exec tiene éxito y se ejecuta el segundo comando en Exec, ¿seguirá teniendo acceso a la variable '{}' para eliminar el archivo correcto? – Abs

+0

¿A qué se expande '' {} '? A menos que contenga dos puntos o comas que permanecerán como están. – Marian

258

Un comando -exec se debe terminar con un ; (por lo que en general tienen que escribir o \;';' para evitar interpretion por el shell) o una +. La diferencia es que con ;, el comando se llama una vez por archivo, con +, se llama tan pocas veces como sea posible (generalmente una vez, pero hay una longitud máxima para una línea de comando, por lo que puede dividirse) con todos los nombres de archivo. Vea este ejemplo:

$ 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 

Su comando tiene dos errores:

En primer lugar, se utiliza {};, pero el ; debe ser un parámetro propio.

En segundo lugar, el comando finaliza en el &&. Usted especificó "ejecutar buscar, y si eso fue exitoso, elimine el archivo llamado {};". Si desea utilizar elementos de shell en el comando -exec, debe ejecutarlo explícitamente en un shell, como -exec sh -c 'ffmpeg ... && rm'.

Sin embargo, no debe agregar el {} dentro del comando bash, se producirán problemas cuando haya caracteres especiales. En cambio, puede pasar parámetros adicionales a la cáscara después de -c command_string (ver man sh):

$ ls 
$(echo damn.) 
$ find * -exec sh -c 'echo "{}"' \; 
damn. 
$ find * -exec sh -c 'echo "$1"' - {} \; 
$(echo damn.) 

Ves lo $ es evaluada por el shell en el primer ejemplo.Imagínese que había un archivo llamado $(rm -rf /) :-)

(Nota al margen: El - no es necesaria, pero la primera variable después de la orden se asigna a la variable $0, que es una variable especial, que normalmente contiene el nombre del programa siendo dirigido y estableciendo que a un parámetro es un poco sucio, a pesar de que no causará ningún daño aquí, probablemente, por lo que establecer que sólo - y empezar con $1.)

así que su comando podría ser algo así como

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

Pero hay una mejor manera. encuentra soportes and y or, por lo que puede hacer cosas como find -name foo -or -name bar. Pero eso también funciona con -exec, que se evalúa como verdadero si el comando sale exitosamente, y para falso si no. Vea este ejemplo:

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

sólo se realiza la impresión si el comando fue con éxito, lo que lo hizo para true pero no para false.

Así que puede usar dos instrucciones ejecutivas encadenadas con un -and, y solo ejecutará el último si el primero se ejecutó correctamente.

+2

La clave parece ser la línea de Marian de "the; is an arg por sí mismo", que es lo que hizo por mí, bombilla sabio y para mi código de muestra. Gracias. – pjammer

+1

Esa es la mejor descripción que he leído en -exec. Es extremadamente poderoso, pero siempre me resulta difícil obtener la sintaxis correcta para él. Esto hizo algunas cosas mucho más claras. Particularmente envolviendo el comando en el caparazón separado. Bonito. Gracias. – Eurospoofer

+2

Tenga en cuenta que '-and' y' -or' no son portátiles. [POSIX especifica '-a' y' -o'] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html), y de hecho '-a' siempre se asume (por lo tanto, no es necesario) . –

35

Intenta poner un espacio antes de cada \;

Obras:

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

no funciona:

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

Esto me dispara con bastante frecuencia. Uno de estos días, agregaré un espacio por defecto. – harperville

+0

Para mí, funciona todo lo contrario en Cygwin en Windows 7: sin espacio antes \; funciona, con espacio, no. Pero si elimino \, con espacio antes; funciona, y sin espacio antes; no es así, tal como se describe aquí. – WebComer

7

Sólo para su información:
He intentado utilizar "encontrar -exec" comando en un sistema Cygwin (UNIX emulado en Windows), y parece que la barra invertida antes del punto y coma debe eliminarse:
find ./ -name "blabla" -exec wc -l {} ;

+0

Realmente confundido. 'find/etc/nginx -name '* .conf' -exec echo {};' y 'find/etc/nginx -name '* .conf' -exec echo {} \;' dio el mismo resultado. :( – Kirby

+0

Estoy ejecutando el shell Bash que viene con Git para Windows, y la respuesta de Dustin Cowles funciona para mí. En otras palabras: sin comillas, barra invertida escapada por punto y coma, espacio después de '{}'. – mamacdon

2

En caso de que alguien vea una similar "missing -exec args" en las secuencias de comandos de Amazon Opsworks Chef bash, necesito agregar otra barra invertida para escapar de la \;

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

Además, si alguien más tiene la "encontrará: argumento que falta a -exec" esto podría ayudar:

En algunas conchas que no es necesario para hacer el escape, es decir, que no es necesario la "\" delante del ";"

find <file path> -name "myFile.*" -exec rm - f {} ; 
-1

Si aún obtiene "find: missing argument to -exec" intente envolver el argumento execute entre comillas.

find <file path> -type f -exec "chmod 664 {} \;" 
Cuestiones relacionadas