Zoek: Ontbrekend argument voor -exec

Ik heb vandaag geholpen met een commando, maar het lijkt niet te werken. Dit is de opdracht:

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

De shell retourneert

find: missing argument to `-exec'

Wat ik in principe probeer te doen, is door een map recursief doorgaan (als het andere mappen heeft) en de FFMPEG-opdracht uitloopt op de .rmbestandstypen en converteren naar .mp3bestandstypen. Zodra dit is gebeurd, verwijdert u de .rm-bestand die net is geconverteerd.

Ik waardeer elke hulp hierbij.


Antwoord 1, Autoriteit 100%

A -exec-opdracht moet worden beëindigd met een ;(dus u moet meestal \;of ';'Om interpretatie door de schaal te voorkomen) of een +. Het verschil is dat met ;, de opdracht eenmaal per bestand wordt genoemd, met +, het wordt net zo paar keer mogelijk genoemd (meestal eenmaal, maar er is een maximum Lengte voor een opdrachtregel, dus het kan worden opgesplitst) met alle bestandsnamen. Zie dit voorbeeld:

$ 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

Uw opdracht heeft twee fouten:

Ten eerste gebruikt u {};, maar de ;moet een eigen parameter zijn.

Ten tweede eindigt het commando op de &&. Je specificeerde “voer de zoekopdracht uit en als dat gelukt is, verwijder dan het bestand met de naam {};.“. Als u shell-dingen in de opdracht -execwilt gebruiken, moet u deze expliciet in een shell uitvoeren, zoals -exec sh -c 'ffmpeg ... && rm'.

U moet echter niet de {} in het bash-commando toevoegen, dit zal problemen opleveren als er speciale tekens zijn. In plaats daarvan kun je aanvullende parameters aan de shell doorgeven na -c command_string(zie man sh):

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

Je ziet dat het $ding wordt geëvalueerd door de shell in het eerste voorbeeld. Stel je voor dat er een bestand was met de naam $(rm -rf /)🙂

(Kanttekening: de -is niet nodig, maar de eerste variabele na de opdracht wordt toegewezen aan de variabele $0, een speciale variabele die normaal gesproken de naam bevat van het programma dat wordt uitgevoerd en dat instellen op een parameter is een beetje onrein, hoewel het hier waarschijnlijk geen kwaad zal doen, dus stellen we dat in op gewoon -en beginnen we met $1.)

Dus je commando kan zoiets zijn als

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

Maar er is een betere manier. find ondersteunt anden or, dus je kunt dingen doen als find -name foo -or -name bar. Maar dat werkt ook met -exec, die evalueert naar waar als de opdracht succesvol wordt afgesloten, en naar onwaar als dat niet het geval is. Zie dit voorbeeld:

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

Het voert de afdruk alleen uit als het commando succesvol was, wat het deed voor truemaar niet voor false.

Je kunt dus twee exec-statements gebruiken, geketend met een -and, en het laatste wordt alleen uitgevoerd als het eerste succesvol is uitgevoerd.


Antwoord 2, autoriteit 17%

Ik heb het nu door. Als je twee commando’s in exec moet uitvoeren in een vondst, moet je eigenlijk twee aparte execs hebben. Dit werkte uiteindelijk voor mij.

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

Antwoord 3, autoriteit 15%

Probeer een spatie te plaatsen voor elke \;

Werkt:

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

Werkt niet:

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

Antwoord 4, autoriteit 2%

Ter informatie:
Ik heb zojuist geprobeerd de opdracht “find -exec” te gebruiken op een Cygwin-systeem (UNIX geëmuleerd op Windows), en daar lijkt het erop dat de backslash vóór de puntkomma moet worden verwijderd:
find ./ -name "blabla" -exec wc -l {} ;


Antwoord 5, autoriteit 2%

Je moet een spatie plaatsen tussen {}en \;

Dus het commando zal zijn als:

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

Antwoord 6

Voor het geval iemand een soortgelijke “missing -exec args” ziet in bash-scripts van Amazon Opsworks Chef, moest ik nog een backslash toevoegen om te ontsnappen aan de \;

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

Antwoord 7

Ook als iemand anders het “find: missing argument to -exec” heeft, kan dit helpen:

In sommige shells hoef je niet te ontsnappen, d.w.z. je hebt de “\” voor de “;” niet nodig.

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

Antwoord 8

Je moet een beetje ontsnappen denk ik.

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

Antwoord 9

Voor iedereen die problemen heeft bij het gebruik van GNU, zoek binair in een Windows-opdrachtprompt. De puntkomma moet worden geëscaped met ^

find.exe . -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 ^;

Antwoord 10

Zowel {} als && zal problemen veroorzaken als gevolg van worden uitgebreid door de opdrachtregel. Ik stel voor om te proberen:

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

Antwoord 11

Als je nog steeds “find: missing argument to -exec” krijgt, probeer dan het argument execute tussen aanhalingstekens te plaatsen.

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

Other episodes