Почему я получаю 4 вызова вместо 3 при использовании этого find -execdir {} + (plus)?

8

Я прочитал здесь, что вы можете посчитать количество вызовов commandв -exec command {} +, отправив по трубке | wc -lдо конца.

Хотя я понимаю, что -execdirэто отличается, в том, что для каждого соответствующего подкаталога, который findобнаруживает, он запускает вызов commandиз подкаталога, в котором он содержится, если у меня более одного файла, который совпадает в подкаталоге, я в итоге получаю количество вызовов, равное количеству соответствующих подкаталогов, а не количество вызовов, соответствующих количеству соответствующих файлов в этих подкаталогах?

Я заканчиваю с последним, когда я запускаю следующее:

$ find . -name "bob*" -execdir echo {} + | wc -l

Страница справочника для execdir command {} +государств заявляет, что первое должно иметь место:

Как и в случае с -execдействием, в +форме -execdirбудет создана командная строка для обработки более одного сопоставленного файла, но при любом вызове из commandэтого списка будут перечислены только файлы, которые существуют в одном подкаталоге.


т.е.

Я получаю:

./file1inDir1
./file2inDir1
./file3InDir2
./file4InDir3

Когда я ожидаю этого, основываясь на справочной странице:

./file1inDir1 ./file2inDir1
./file3InDir2
./file4InDir3
leeand00
источник
Вы не можете рассчитывать вызовы команд таким образом. Если команда есть echoи аргументы генерируются, {} +а у вас нет новых строк в именах файлов (большинство людей этого не делают), ТОГДА число строк - это количество вызовов, и это работает. Если команда говорит, head -n 999000 /dev/urandomэто идет ужасно неправильно.
dave_thompson_085

Ответы:

11

Это проблема производительности find. В findutilsверсии 4.3.4 обходной путь должен был ограничить число аргументов, которые -execdir ... {} +будут использовать 1. В версии 4.5.9 ограничение было снято.

Смотрите пример:

$ mkdir -p dir{1..3}
$ touch dir{1..3}/file1 dir2/file{1..3}
$ find
.
./dir1
./dir1/file1
./dir2
./dir2/file1
./dir2/file2
./dir2/file3
./dir3
./dir3/file1

При -execdir {} +этом команда должна быть выполнена 3 раза. Второй вызов должен иметь 3 аргумента.

С find4.4.2:

$ find-4.4.2 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 in /path/to/dir2
Executing ./file2 in /path/to/dir2
Executing ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3

С find4.6.0:

$ find-4.6.0 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 ./file2 ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3
хаос
источник