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 .rm
bestandstypen en converteren naar .mp3
bestandstypen. 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 -exec
wilt 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 and
en 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 true
maar 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 {} \;"