@StephaneChazelas опубликовал следующее решение этого вопроса и ответа:Возникли некоторые проблемы с использованием «find -exec {} +».
$ find . -iname "*.extension" -exec sh -c '
exec <command> "$@" <additional parameters>' sh {} +
Что именно здесь происходит? Что конкретно делает последний sh {}
? Кажется, он нужен только для того, чтобы успокоить -exec
команду find, чтобы она могла что-то делать, NOOP.
Я мог бы так же легко echo {}
это сделать, и, похоже, все будет работать нормально.
решение1
Синтаксис следующий:
find ... -exec cmd {} +
find
найдет несколько файлов на основе критериев, указанных в, ...
и запустит их cmd
с этим списком путей к файлам в качестве аргументов, насколько это возможно, не превышая при этом ограничение на размер аргументов команды.
При необходимости он может разделить список файлов и вызвать cmd
несколько раз. Например, он может вызвать:
cmd ./file1 ./file2 ... ./file3000
cmd ./file3001 ./file3002 ... ./file4321
Ограничение в том, что это {}
должно быть последним. Например, вы не можете написать:
find ... -exec cmd {} other args +
как вы могли бы ';'
вместо '+'
.
Ты можешь написать:
find ... -exec echo foo {} +
но нет:
find ... -exec echo {} foo +
Итак, если вам действительно нужно добавить какие-то дополнительные аргументы cmd
после списка файлов, вам придется прибегнуть к вызову оболочки. (Другими причинами, по которым вам может понадобиться вызвать оболочку, могут быть случаи, когда вам нужно использовать такие функции оболочки, как перенаправления, каналы, некоторые расширения строк...)
В sh -c 'inline-script' x a b c
, для inline-script
, $0
есть x
, $1
есть a
, $2
есть b
... так же "$@"
есть список этих 3 аргументов: a, b и c. Так что в:
find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +
Длявстроенный скрипт, $0
(который используется, например, при отображении сообщений об ошибках) имеет значение find-sh
и "$@"
представляет собой список файлов (то, во что он find
расширяется {}
).
Используя exec
специальную встроенную функцию оболочки:
find ... -exec sh -c 'exec cmd "$@" other arg' find-sh {} +
Мы говорим оболочке не запускать дополнительный процесс для запуска cmd
, а вместо этого запустить его в том же процессе (заменяя запущенный процесс оболочки этой командой). Некоторые оболочки, такие как zsh
и некоторые реализации ksh
делают это неявно для последней команды во встроенном скрипте (также bash
когда во встроенном скрипте только одна команда, как здесь).