-exec
Команда должна быть прекращена с ;
(так обычно нужно ввести \;
или , ';'
чтобы избежать interpretion оболочки) или +
. Разница в том, что с ;
, команда вызывается один раз для файла, с +
, она вызывается как можно меньше раз (обычно один раз, но максимальная длина для командной строки, поэтому она может быть разделена) со всеми именами файлов , Смотрите этот пример:
$ 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
, и последний будет выполнять только последний, если первый был успешно выполнен.
-and
и-or
не являются портативными. POSIX определяет-a
и-o
, и фактически-a
всегда предполагается (следовательно, не требуется)."\;"
не работает, но" \;"
работаетЯ понял это сейчас. Когда вам нужно запустить две команды в exec в находке, вам нужно иметь два отдельных исполнителя. Это, наконец, сработало для меня.
источник
echo
перед командами и посмотрите, что он делает.echo
довольно ненадежен - вы не можете определить разницу междуecho "one argument"
иecho one argument
(выходные данные последнего являются ложными, поскольку на самом деле они передаютecho
два совершенно разных аргумента). Гораздо лучше сделать что-то вроде этого-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'
, который будет печатать вывод таким образом, чтобы сделать непечатаемые символы видимыми, чтобы вы могли обнаружить новые строки DOS и другие странности.Попробуйте поставить пробел перед каждым \;
Работает:
Не работает:
источник
Просто для вашей информации:
я только что попытался использовать команду "find -exec" в системе Cygwin (UNIX эмулируется в Windows), и там кажется, что обратная косая черта перед точкой с запятой должна быть удалена:
find ./ -name "blabla" -exec wc -l {} ;
источник
find /etc/nginx -name '*.conf' -exec echo {} ;
иfind /etc/nginx -name '*.conf' -exec echo {}\;
дал тот же результат. :({}
.На всякий случай, если кто-нибудь увидит подобные «отсутствующие аргументы -exec» в сценариях bash Amazon Opsworks Chef, мне нужно добавить еще одну обратную косую черту, чтобы избежать \;
источник
Также, если у кого-то есть «find: отсутствующий аргумент для -exec», это может помочь:
В некоторых оболочках вам не нужно выполнять экранирование, т. Е. Вам не нужно "\" перед ";".
источник
;
Не цитируют или спасшийся здесь означает , что он может потребляться оболочки, а не читатьfind
. Также-f
и- f
это две разные вещи.Тебе нужно сбежать, я думаю.
источник
И {}, и && вызовут проблемы из-за того, что будут расширены командной строкой. Я бы предложил попробовать:
источник
{}
переменной для удаления нужного файла?{}
расширяешься? Если он не содержит двух точек или запятых, которые останутся такими, как есть.Вы должны поставить пробел между
{}
и\;
Таким образом, команда будет выглядеть так:
источник
Если вы все еще получаете «find: отсутствующий аргумент для -exec», попробуйте заключить аргумент execute в кавычки.
источник