-exec
Komenda 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 -exec
poleceniu, 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 and
i 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, true
ale 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.
-and
i-or
nie są przenośne. POSIX określa-a
i-o
faktycznie-a
jest zawsze zakładany (stąd nie jest potrzebny)."\;"
nie działa, ale" \;"
działaTeraz to rozgryzłem. Kiedy musisz uruchomić dwie komendy w exec w znalezieniu, musisz mieć dwa osobne exec. To w końcu zadziałało dla mnie.
źródło
echo
przed poleceniami i zobacz, co robi.echo
jest dość niewiarygodny - nie można odróżnić międzyecho "one argument"
iecho one argument
(wynik tego ostatniego jest fałszywy, ponieważ w rzeczywistości przekazujeecho
dwa całkowicie odrębne argumenty). Znacznie lepiej zrobić coś takiego-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'
, co wydrukuje wydruk w taki sposób, aby znaki niedrukowalne były widoczne, dzięki czemu można wykryć znaki nowej linii DOS i inne dziwności.Spróbuj wstawić spację przed każdym \;
Pracuje:
Nie działa:
źródło
Tylko dla twojej informacji:
Właśnie próbowałem użyć polecenia „find -exec” w systemie Cygwin (UNIX emulowanym w systemie Windows) i wydaje się, że ukośnik odwrotny przed średnikiem należy usunąć:
find ./ -name "blabla" -exec wc -l {} ;
źródło
find /etc/nginx -name '*.conf' -exec echo {} ;
ifind /etc/nginx -name '*.conf' -exec echo {}\;
dał ten sam wynik. :({}
.Na wypadek, gdyby ktoś widział podobne „brakujące argumenty -exec” w skryptach bash Amazon Opsworks Chef, musiałem dodać kolejny ukośnik odwrotny, aby uciec przed \;
źródło
Ponadto, jeśli ktoś inny ma argument „find: missing argument -exec”, może to pomóc:
W niektórych powłokach nie musisz uciekać, tzn. Nie potrzebujesz „\” przed „;”.
źródło
;
Nie są notowane lub uciekł tutaj oznacza, że mogą być spożywane przez powłokę, nie czytana przezfind
. Ponadto,-f
i- f
są dwie różne rzeczy.Myślę, że musisz uciec.
źródło
Zarówno {}, jak i && będą powodować problemy z powodu rozszerzenia przez wiersz poleceń. Proponuję spróbować:
źródło
{}
zmiennej umożliwiającej usunięcie odpowiedniego pliku?{}
rozwija? Chyba że zawiera dwie kropki lub przecinki, które pozostaną bez zmian.Musisz umieścić spację między
{}
i\;
Więc polecenie będzie wyglądało tak:
źródło
Jeśli nadal pojawia się komunikat „find: missing argument to -exec”, spróbuj zawrzeć argument wykonania w cudzysłowach.
źródło