rechercher: argument manquant à-exec

, j'ai été aidé aujourd'hui avec une commande, mais il ne semble pas fonctionner. C'est la commande:

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

Le shell renvoie

find: missing argument to `-exec'

Ce que j'essaie essentiellement de faire est de parcourir un répertoire récursivement (s'il a d'autres répertoires) et d'exécuter la commande ffmpeg sur les types de fichiers .rm et de les convertir en types de fichiers .mp3. Une fois cela fait, supprimez le fichier .rm qui vient d'être converti.

J'apprécie toute aide à ce sujet.

168
demandé sur shgnInc 2010-06-03 01:19:25

9 réponses

Une commande -exec doit être terminée par un ; (vous devez donc généralement taper \; ou ';' pour éviter l'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 a deux erreurs:

Tout d'Abord, vous utilisez {};, mais le ; doit être un paramètre propre.

Deuxièmement, la commande se termine au &&. Vous avez spécifié " exécuter find, Et si cela a réussi, supprimez le fichier nommé {};.". Si vous voulez utiliser des éléments shell dans la commande -exec, vous devez l'exécuter explicitement dans un shell, tel que -exec sh -c 'ffmpeg ... && rm'.

Cependant, vous ne devriez pas ajouter le {} dans la commande bash, cela produira des problèmes lorsqu'il y aura 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 avait un fichier appelé $(rm -rf /) :-)

(note latérale: le - n'est pas nécessaire, mais la première variable après la commande est assignée à la variable $0, qui est une variable spéciale contenant normalement le nom du programme en cours d'exécution et le définir sur un paramètre est un peu impur, bien que cela ne causera probablement aucun dommage ici, donc nous mettons cela à juste - $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. trouvez les supports and et or, Vous pouvez donc 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 sinon. Voir cet exemple:

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

Il n'exécute l'impression que si la commande a réussi, ce qu'il a fait pour true mais pas pour false.

Vous pouvez donc utiliser deux instructions exec enchaînées avec un -and, et il n'exécutera ce dernier que si le premier a été exécuté avec succès.

287
répondu Marian 2016-10-02 12:28:15

Je l'ai compris maintenant. Lorsque vous devez exécuter deux commandes dans exec dans une recherche, vous devez avoir deux exécuteurs distincts. Cela a finalement fonctionné pour moi.

find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \;
50
répondu Abs 2010-06-02 21:44:52

, Essayez de mettre un espace avant chaque \;

Fonctionne:

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

Ne fonctionne pas:

find . -name "*.log" -exec echo {}\;
44
répondu Dustin Cowles 2014-08-04 04:42:29

Juste pour votre information:
Je viens d'essayer d'utiliser la commande "find-exec" sur un système Cygwin (UNIX émulé sous Windows), et il semble que la barre oblique inverse avant le point-virgule doit être supprimée:
find ./ -name "blabla" -exec wc -l {} ;

7
répondu Dominique 2015-09-03 14:01:35

Juste au cas où quelqu'un voit un "args-exec manquant" similaire dans les scripts Amazon Opsworks Chef bash, j'avais besoin d'ajouter une autre barre oblique inverse pour échapper au\;

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\;
  EOH
  ignore_failure true
end
2
répondu John Cooper 2015-09-29 14:34:16

En outre, si quelqu'un d'autre a le "find: argument manquant à-exec" cela pourrait aider:

Dans certains shells, vous n'avez pas besoin de faire l'échappement, c'est-à-dire que vous n'avez pas besoin du "\" devant le ";".

find <file path> -name "myFile.*" -exec rm - f {} ;
2
répondu sellmaurer 2016-03-03 19:37:05

Vous devez faire un peu d'évasion je pense.

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} \-sameq {}.mp3 \&\& rm {}\;
1
répondu Matthew Smith 2010-06-02 21:41:49

Les deux {} et & & causeront des problèmes en raison d'être développés par la ligne de commande. Je suggère d'essayer:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \;
0
répondu VeeArr 2010-06-02 21:47:42

Si vous obtenez toujours "find: missing argument to-exec", essayez d'envelopper l'argument execute entre guillemets.

find <file path> -type f -exec "chmod 664 {} \;"
-2
répondu woo 2017-01-05 10:25:28