Команда
A -exec
должна заканчиваться ;
(поэтому обычно вам нужно набрать \;
или ';'
, чтобы избежать интерпретации оболочкой) или +
. Разница в том, что при ;
команда вызывается один раз для файла, при +
она вызывается как можно меньше раз (обычно один раз, но максимальная длина для командной строки, поэтому она может быть разделить) со всеми именами файлов. Смотрите этот пример:
$ 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
Ваша команда имеет две ошибки:
Сначала вы используете {};
, но ;
должен быть собственным параметром.
Во-вторых, команда заканчивается на &&
. Вы указали «выполнить поиск, и, если это было успешно, удалите файл с именем {};
.«. Если вы хотите использовать содержимое оболочки в команде -exec
, вам нужно явно запустить ее в оболочке, например, -exec sh -c 'ffmpeg ... && rm'
.
Однако вы не должны добавлять {} в команду bash, это вызовет проблемы при наличии специальных символов. Вместо этого вы можете передать дополнительные параметры в оболочку после -c command_string
(см. man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Вы видите, что $
вещь оценивается оболочкой в первом примере. Представьте, что есть файл с именем $(rm -rf /)
: -)
(Примечание: -
не требуется, но первая переменная после команды присваивается переменной $0
, которая представляет собой специальную переменную, обычно содержащую имя запускаемой программы и устанавливающую его в Параметр немного нечист, хотя здесь он, вероятно, не причинит никакого вреда, поэтому мы устанавливаем его равным -
и начинаем с $1
.)
Так что ваша команда может быть что-то вроде
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Но есть и лучший способ. найдите поддержку and
и or
, так что вы можете делать что-то вроде find -name foo -or -name bar
. Но это также работает с -exec
, который оценивается как истина, если команда успешно завершается, и ложь, если нет. Смотрите этот пример:
$ ls
false true
$ find * -exec {} \; -and -print
true
Печать выполняется только в том случае, если команда была успешно выполнена, что она сделала для true
, но не для false
.
Таким образом, вы можете использовать два оператора exec, связанные с -and
, и он будет выполнять последний, только если первый был успешно выполнен.