Ответ 1
В дополнение к другим тонким ответам GNU find (по крайней мере) имеет предикат -quit
:
find path -other -predicates \( -exec cmd {} \; -o -quit \)
Предикат -quit
конечно нестандартный и не существует в поиске BSD.
Я хочу запустить команду
find some/path -exec program \{} \;
но я хочу, чтобы команда find вышла, как только команда
program \{}
не удается найти ни один из найденных файлов.
Есть ли простой способ сделать это?
В дополнение к другим тонким ответам GNU find (по крайней мере) имеет предикат -quit
:
find path -other -predicates \( -exec cmd {} \; -o -quit \)
Предикат -quit
конечно нестандартный и не существует в поиске BSD.
Я думаю, что невозможно достичь того, чего вы хотите, только с find -exec
.
Ближайшей альтернативой было бы сделать pipe find
до xargs
, например:
find some/path -print0 | xargs -0 program
или
find some/path -print0 | xargs -0L1 program
Это прекратится, если программа завершится с ненулевым статусом выхода
print0
, так что файлы с символами новой строки в их именах могут обрабатываться-0
необходимо, когда используется -print0
L1
сообщает программе xargs
выполнить программу с одним аргументом за раз (по умолчанию нужно добавить все аргументы в одно исполнение программы)Если у вас есть только правильные имена файлов, вы можете упростить это:
find some/path | xargs program
или
find some/path | xargs -L1 program
Наконец, если программа принимает более одного аргумента, вы можете использовать -i
в сочетании с {}
. Например.
find some/path | xargs -i program param1 param2 {} param4
Вы можете передать вывод из find
в другой подпроцесс и использовать while
/break
:
find some/path | while read f
do
program $f
if [ $? -ne 0 ]
then
break
fi
done
% _find_trap() {
> _find_pid="${1}" ; _find_ops="${2}" ; _find_trigger="${3}"
> shift 3 && set -- "${@}"
> trap 'kill -s INT "-${_find_pid}" \
> unset _find_pid _find_ops _find_trigger ; set - \
> 1>&2 printf "%s" "find killed due to trap" \
> exit [CODE] ' TRAP
> while { sh -c "${_find_ops} ${@}"} {
> [ "${_find_trigger}" ] && { kill -s TRAP "-${_find_pid}" ; break ; }
> ...
> }
> export -f _find_trap ; find . -execdir _find_trap \"$$\" \"${cmds}\" \
> \"${testable_trigger}\" "{}" +
Вот мой пример для "системы сборки", которая останавливается после попадания первой ошибки компилятора (на основе ответа Коджиро, который не работал у меня):
(Необходимость в скопированных скобках реальна. Я знаю, что это больно.)
find -name '*.cpp' \( -print -a -exec g++ -c {} \; -o -quit \)
Я хочу создать статическую библиотеку в основном всех файлов С++, расположенных в текущем каталоге и ниже.
Перед запуском компилятора я хочу иметь файл -print
-ed, затем -exec
-ed, но когда он терпит неудачу (и оставляет ошибки на stderr
, он должен -quit
.
-a
похож на &&
, а -o
похож на ||
в оболочке или C.
Без круглых скобок GNU находит "оптимизирует" запрос, сначала попробовав наиболее вероятное условие, которое - я думаю - -quit
.