Pourquoi est-ce qui find
imprime un conduit ./
à des résultats si aucun chemin n'est indiqué?
$ find
./file1
./file2
./file3
Quelle est la raison de ne pas l'imprimer?
$ find
file1
file2
file3
La raison pour laquelle vous voyez cela est que le développeur de GNU a choisi de fournir un comportement "raisonnable" quand aucun chemin n'est indiqué. En revanche, POSIX n'indique pas que le paramètre est facultatif:find
find
L'
find
utilitaire doit récursivement descendre la hiérarchie de répertoires de chaque fichier spécifié par chemin , en évaluant une expression booléenne composée des primaires décrites dans la section OPERANDS pour chaque fichier rencontré. Chaque opérande de chemin doit être évalué tel qu'il a été fourni, y compris tous les<slash>
caractères de fin ; tous les chemins d'accès pour les autres fichiers rencontrés dans la hiérarchie doivent consister en la concaténation de l'opérande de chemin d'accès actuel, a<slash>
si l'opérande de chemin d'accès actuel ne s'est pas terminé par un, et le nom de fichier relatif à l'opérande de chemin d'accès. La partie relative ne doit contenir aucun composant point ou point-point, pas de finet uniquement des<slash>
caractères uniques entre les composants de chemin d'accès.
Vous pouvez voir la différence dans le synopsis pour chacun. GNU a (comme c'est la convention) des éléments optionnels entre crochets:
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
[expression]
alors que POSIX n'indique pas qu'il peut être facultatif:
find [-H|-L] path... [operand_expression...]
Dans le programme GNU, cela se fait en ftsfind.c
:
si (vide) { / * * Nous utilisons ici une variable temporaire car certaines actions modifient * le chemin temporairement. Par conséquent, si nous utilisons une constante de chaîne, * nous obtenons un coredump. Le meilleur exemple de cela est si nous disons * "find -printf% H" (notez, pas "find. -printf% H"). * / char defaultpath [2] = "."; return find (defaultpath); }
et un littéral "."
est utilisé pour plus de simplicité. Vous verrez donc le même résultat avec
find
et
find .
car (et POSIX est d'accord) le chemin donné sera utilisé pour préfixer les résultats (voir ci-dessus pour la concaténation ).
Avec un peu de travail, on pouvait déterminer quand la fonctionnalité a été ajoutée pour la première fois; il était présent lors de la création initiale de "findutils" en 1996 (voir find.c
):
+ /* If no paths are given, default to ".". */
+ for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+ process_top_path (argv[i]);
+ if (i == 1)
+ process_top_path (".");
+
+ exit (exit_status);
+}
Dans le journal des modifications de la découverte 3.8, cela était apparemment
Sat Dec 15 19:01:12 1990 David J. MacKenzie (djm at egypt)
* find.c (main), util.c (usage): Make directory args optional,
defaulting to "."
Habituellement, on fait un post-traitement des fichiers et, dans ce cas, il peut y avoir un énorme avantage à démarrer le nom de fichier avec ./
. En particulier, si un nom de fichier commence par -
, une commande ultérieure pourrait interpréter ce nom de fichier comme une option. ./
évite cela.
Par exemple, considérons un répertoire avec ces fichiers:
$ ls
--link --no-clobber
Maintenant, imaginez comment cette commande fonctionnerait si les noms de fichiers étaient fournis sans le ./
devant:
$ find -type f -exec cp -t ../ {} +
Nous pouvons illustrer le problème avec find
lui-même. Exécutons-le dans le même répertoire que ci-dessus. Les oeuvres suivantes:
$ find ./*
./--link
./--no-clobber
Échoue:
$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.
find *
.file
demandent à l'utilisateur de donner un chemin (comme la découverte BSD sur OS X). Donc, vous devez généralement dire explicitement quelque chose commefind . -type f ...
. À partir de là, ce n'est pas un grand pas pour certaines versions de find (comme GNU find) de simplement par défaut.
et de laisser tout le reste tel quel.find *
ne pas afficher le.
est parce que*
répertorie tous les fichiers et dossiers, mais exclut.
. Faites-leecho *
dans un répertoire qui ne contient qu'un ou deux fichiers, et vous verrez qu'il.
n'est pas répertorié. Ainsi,find *
opère sur chaque fichier développé. C'est la même chose que si vous aviez ditfind Desktop/
depuis le répertoire personnel. Vous verrez la sortie commeDesktop/foo_bar.txt
find
se comporter ainsi. Avez-vous des informations de référence faisant autorité pour étayer l'allégation implicite qui afind
été conçue pour se comporter de cette manière pour cette raison?La
find
commande a besoin de chemin (s) pour rechercher. Si nous n'en spécifions aucun, il utilise le répertoire courant (.
) comme point de départ. De même, si vous passez le chemin, par exemple/tmp
, il considère cela comme son point de départ. Et donc les résultats.Si répertoire courant:
Si
/tmp
répertoire:Si
abc
répertoire sous le répertoire courant:Si plusieurs répertoires sous le répertoire actuel:
la source
find
besoin d'un chemin pour rechercher quoi que ce soit et qu'il par défaut dans le répertoire actuel. La question est de savoir pourquoi il imprime le./
début quandfile.txt
est le même que./file.txt
.Si vous ne spécifiez pas de chemin, la
find
commande suppose${PWD}
que comme chemin et l'imprime sur sa sortie. L'utilisateur qui ne spécifie pas le chemin ne change pas lefind
fonctionnement. Et find fonctionne toujours avec les chemins par défaut.la source
/tmp
, ce$PWD
n'est/tmp
pas le cas./
./tmp
, exécutez la commandefind /tmp
Si vous ne spécifiez pas de chemin, ce sera toujours le répertoire courant, qui est./
/tmp
. C'est que ça ne peut pas être$PWD
.${PWD}
étaient le verbiage incorrectfind .
,find $PWD
etfind
(sans chemin, si votre recherche le prend en charge).