Une -execcommande doit être terminée par un ;(vous devez donc généralement taper \;ou ';'éviter une interprétation par le shell) ou un +. La différence est qu'avec ;, la commande est appelée une fois par fichier, avec +elle est appelée aussi peu de fois que possible (généralement une fois, mais il y a une longueur maximale pour une ligne de commande, donc elle peut être divisée) avec tous les noms de fichiers . Voir cet exemple:
$ 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
Votre commande comporte deux erreurs:
Tout d'abord, vous utilisez {};, mais le ;doit être un paramètre qui lui est propre.
Deuxièmement, la commande se termine à &&. Vous avez spécifié «exécuter la recherche, et si cela a réussi, supprimez le fichier nommé {};.». Si vous souhaitez utiliser des éléments shell dans la -execcommande, vous devez l'exécuter explicitement dans un shell, tel que -exec sh -c 'ffmpeg ... && rm'.
Cependant, vous ne devez pas ajouter le {} dans la commande bash, cela produira des problèmes lorsqu'il y a des caractères spéciaux. Au lieu de cela, vous pouvez passer des paramètres supplémentaires au shell après -c command_string(voir man sh):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Vous voyez que la $chose est évaluée par le shell dans le premier exemple. Imaginez qu'il y ait un fichier appelé $(rm -rf /):-)
(Note latérale: le -n'est pas nécessaire, mais la première variable après la commande est affectée à la variable $0, qui est une variable spéciale contenant normalement le nom du programme en cours d'exécution et la définition d'un paramètre est un peu impure, même si elle a gagné ne causera probablement aucun mal ici, nous avons donc réglé cela juste -pour commencer $1.)
Donc, votre commande pourrait être quelque chose comme
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Mais il y a une meilleure façon. trouver des supports andet or, donc vous pouvez faire des choses comme find -name foo -or -name bar. Mais cela fonctionne également avec -exec, qui évalue à true si la commande se termine avec succès et à false dans le cas contraire. Voir cet exemple:
$ ls
false true
$ find * -exec {} \; -and -print
true
Il exécute l'impression uniquement si la commande a réussi, ce qu'elle a fait pour truemais pas pour false.
Vous pouvez donc utiliser deux instructions exec chaînées avec un -and, et il n'exécutera ce dernier que si le premier a été exécuté avec succès.