Pourquoi est-ce que je me retrouve avec 4 invocations au lieu de 3 lorsque j'utilise ce find -execdir {} + (plus)?

8

J'ai lu ici que vous pouvez compter le nombre d'appels de commandin -exec command {} +en canalisant | wc -ljusqu'à la fin.

Bien que je comprenne que -execdirc'est différent, en ce que, pour chaque sous-répertoire correspondant qui finddécouvre, il exécute une invocation du commanddepuis le sous-répertoire dans lequel il est contenu, si j'ai plus d'un fichier qui correspond dans un sous-répertoire, ne devrait pas 'ai-je fini avec le nombre d'appels égal au nombre de sous-répertoires correspondants, et non pas le nombre d'invocations correspondant au nombre de fichiers correspondants dans ces sous-répertoires?

Je me retrouve avec ce dernier lorsque je lance ce qui suit:

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

La page de manuel pour les execdir command {} +états que le premier devrait être le cas:

Comme pour l' -execaction, la +forme de -execdirva construire une ligne de commande pour traiter plus d'un fichier correspondant, mais toute invocation donnée de commandne listera que les fichiers qui existent dans le même sous-répertoire.


c'est à dire

Je suis en train:

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

Quand je m'attends à cela, basé sur la page de manuel:

./file1inDir1 ./file2inDir1
./file3InDir2
./file4InDir3
leeand00
la source
Vous ne pouvez pas compter les invocations de commandes en général de cette façon. Si la commande est echoet que les arguments sont générés par {} +et que vous n'avez pas de nouvelles lignes dans vos noms de fichiers (la plupart des gens n'en ont pas) ALORS le nombre de lignes est le nombre d'appels et cela fonctionne. Si le commandement est dit, head -n 999000 /dev/urandomcela tourne horriblement mal.
dave_thompson_085

Réponses:

11

Il s'agit d'un problème de performances de find. Dans la findutilsversion 4.3.4, une solution de contournement a dû limiter le nombre d'arguments à -execdir ... {} +utiliser à 1. Dans la version 4.5.9, la limite a été supprimée.

Voir un exemple:

$ 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

Avec -execdir {} +, la commande doit être exécutée 3 fois. La deuxième invocation doit avoir 3 arguments.

Avec 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

Avec 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
le chaos
la source