web-dev-qa-db-fra.com

find: argument manquant pour -exec

On m'a aidé aujourd'hui avec une commande, mais cela ne semble pas fonctionner. C'est la commande:

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

Le Shell revient

find: missing argument to `-exec'

Ce que j'essaie fondamentalement de faire est de parcourir un répertoire de manière récursive (s'il possède d'autres répertoires), d'exécuter la commande ffmpeg sur les types de fichiers .rm et de les convertir en types de fichiers .mp3. Ceci fait, supprimez le fichier .rm qui vient d'être converti.

J'apprécie toute aide à ce sujet.

189
Abs

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

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

Une commande -exec doit être terminée par un ; (vous devez donc taper \; ou ';' pour éviter toute 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 le moins de fois possible (généralement une fois, mais la longueur maximale d'une ligne de commande est donc il peut être divisé) 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 qui lui est propre.

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

Cependant, vous ne devez pas ajouter le {} à l'intérieur de 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.)

La chose $ est évaluée par le shell dans le premier exemple. Imaginez qu'il y ait un fichier appelé $(rm -rf /) :-)

(Remarque latérale: le - n'est pas nécessaire, mais la première variable après que la commande a été affectée à la variable $0, qui est une variable spéciale contenant normalement le nom du programme en cours d'exécution. un paramètre est un peu impur, bien qu'il ne causera probablement aucun dommage ici, nous avons donc défini ce paramètre uniquement sur - et commençons par $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 un meilleur moyen. find supports and et or, vous pouvez donc faire des choses comme find -name foo -or -name bar. Mais cela fonctionne également avec -exec, qui est évalué à true si la commande se termine correctement 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 associées à un -and, et cette dernière ne sera exécutée que si la précédente a été exécutée avec succès.

312
Marian

Essayez de mettre un espace avant chaque \;

Travaux:

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

Ne fonctionne pas:

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

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 bien que la barre oblique inverse précédant le point-virgule doive être supprimée:
find ./ -name "blabla" -exec wc -l {} ;

7
Dominique

De plus, si quelqu'un a l'argument "find: missing: to -exec", ceci pourrait aider:

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

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

Juste au cas où quelqu'un verrait un "argument -exec manquant" similaire dans les scripts bash d'Amazon Opsworks Chef, je devais ajouter une autre barre oblique inverse pour échapper à 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
2
John Cooper

Je pense que vous devez vous échapper.

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

{} Et && causeront des problèmes en raison de leur développement par la ligne de commande. Je suggérerais d'essayer:

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