Un -exec
comando debe terminarse con a ;
(por lo que generalmente debe escribir \;
o ';'
evitar la interpretación por parte del shell) o a +
. 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 . Ver 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:
Primero, se usa {};
, pero ;
debe ser un parámetro propio.
Segundo, el comando termina en el &&
. Usted especificó "ejecutar find, y si fue exitoso, elimine el archivo llamado {};
". Si desea usar cosas de shell en el -exec
comando, debe ejecutarlo explícitamente en un shell, como -exec sh -c 'ffmpeg ... && rm'
.
Sin embargo, no debe agregar {} dentro del comando bash, producirá problemas cuando haya caracteres especiales. En su lugar, puede pasar parámetros adicionales al shell 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.)
Verá que la $
cosa es evaluada por el shell en el primer ejemplo. Imagine que hay un archivo llamado $(rm -rf /)
:-)
(Nota al margen: -
no es necesario, pero la primera variable después del comando se asigna a la variable $0
, que es una variable especial que normalmente contiene el nombre del programa que se está ejecutando y establecer eso en un parámetro es un poco impuro, aunque ganó Probablemente no cause ningún daño aquí, así que configuramos eso solo -
y comenzamos con $1
).
Entonces tu comando podría ser algo como
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Pero hay una mejor manera. encuentre apoyos and
y or
, para que pueda 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 con éxito, y falso si no. Ver este ejemplo:
$ ls
false true
$ find * -exec {} \; -and -print
true
Solo ejecuta la impresión si el comando fue exitoso, lo que hizo para true
pero no para false
.
Por lo tanto, puede usar dos declaraciones ejecutivas encadenadas con un -and
, y solo ejecutará la última si la primera se ejecutó con éxito.