Réponses:
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.
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 comme find . -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-le echo *
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 dit find 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 a find
é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:
$ find
or
$ find .
output:
./file1
./file2
./file3
Si /tmp
répertoire:
$ find /tmp
output:
/tmp/file4
/tmp/file5
Si abc
répertoire sous le répertoire courant:
$ find abc
output:
abc/file6
abc/file7
Si plusieurs répertoires sous le répertoire actuel:
$ find fu bar
output:
fu/file10
fu/file11
bar/file8
bar/file9
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 quand file.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 le find
fonctionnement. Et find fonctionne toujours avec les chemins par défaut.
/tmp
, ce $PWD
n'est /tmp
pas le cas ./
.
/tmp
, exécutez la commande find /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 incorrect
find .
, find $PWD
et find
(sans chemin, si votre recherche le prend en charge).
find *
.