-execKomenda musi zostać zakończona ;(tak zwykle trzeba wpisać \;lub ';'w celu uniknięcia interpretion przez powłokę) lub +. Różnica polega na tym ;, że z , polecenie jest wywoływane raz na plik, z +, jest wywoływane tak mało razy, jak to możliwe (zwykle raz, ale linia poleceń ma maksymalną długość, więc można ją podzielić) ze wszystkimi nazwami plików . Zobacz ten przykład:
$ 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
Twoje polecenie ma dwa błędy:
Po pierwsze, używasz {};, ale ;musi być własnym parametrem.
Po drugie, polecenie kończy się na &&. Podałeś „uruchom find, a jeśli to się powiedzie, usuń plik o nazwie {};.”. Jeśli chcesz użyć powłoki w -execpoleceniu, musisz jawnie uruchomić ją w powłoce, takiej jak -exec sh -c 'ffmpeg ... && rm'.
Jednak nie należy dodawać {} wewnątrz polecenia bash, spowoduje to problemy, gdy będą znaki specjalne. Zamiast tego możesz przekazać dodatkowe parametry do powłoki po -c command_string(patrz man sh):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Widzisz, że $rzecz jest oceniana przez powłokę w pierwszym przykładzie. Wyobraź sobie, że istnieje plik o nazwie $(rm -rf /):-)
(Uwaga dodatkowa: Nie -jest potrzebna, ale pierwsza zmienna po poleceniu jest przypisana do zmiennej $0, która jest specjalną zmienną zwykle zawierającą nazwę uruchamianego programu i ustawienie tego parametru na parametr jest trochę nieczyste, chociaż wygrało prawdopodobnie nie zaszkodzi tutaj, więc ustawiliśmy to na -początek i zaczynamy od $1).
Więc twoje polecenie może być podobne
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Ale jest lepszy sposób. znajdź wsparcie andi or, więc możesz robić rzeczy takie jak find -name foo -or -name bar. Ale to również działa z -exec, co daje wartość true, jeśli polecenie zakończy się pomyślnie, i false, jeśli nie. Zobacz ten przykład:
$ ls
false true
$ find * -exec {} \; -and -print
true
Uruchamia druk tylko wtedy, gdy polecenie zakończyło się powodzeniem, trueale nie dla false.
Możesz więc użyć dwóch instrukcji exec połączonych łańcuchem z -and, i wykona to drugie, tylko jeśli pierwsza zostanie pomyślnie uruchomiona.