Sur Linux,
cd /tmp mkdir foo; cd foo
Maintenant, courir
find . -name 'foo'
ne donne pas de sortie. Alors que courir
find /tmp/foo -name 'foo'
Donne la sortie /tmp/foo
qui n'a pas de sens pour moi. Quelqu'un peut-il expliquer pourquoi?
find
parcourt l'arborescence de directorys spécifié et évalue l'expression donnée pour chaque file qu'il trouve. La traversée commence au path donné. Voici un résumé de la façon de find . -name foo
find . -name foo
fonctionne:
.
) Correspond-il au motif foo
? Non, alors ne faites rien. /tmp/foo
est un autre nom pour le même directory. Mais find
ne le sait pas (et ce n'est pas supposé essayer de le savoir). .
, et pour chaque input, effectuer le process de traversée.
.
et ..
, qui find
ne traverse pas récursivement. Donc, le travail est terminé. Et find /tmp/foo
:
/tmp/foo
foo
) correspond-il au motif foo
? Oui, donc la condition correspond.
/tmp/foo
, et pour chaque input, effectuer le process de traversée.
.
et ..
, qui find
ne traverse pas récursivement. Donc, le travail est terminé. Il se trouve que cela .
et /tmp/foo
sont le même directory, mais cela ne suffit pas pour garantir que find
ait le même comportement sur les deux. La command find
permet de distinguer les paths d'access au même file; le prédicat -name
est l'un d'entre eux. find /tmp/foo -name foo
correspond au directory de départ ainsi qu'à tout file sous- foo
appelé foo
. find . -name .
correspond uniquement au directory de démarrage (.peu ne peut être trouvé lors d'une traversée récursive).
Il n'y a pas de normalisation des arguments de command line avant l'application des tests. Ainsi, les résultats diffèrent selon le path utilisé (si des liens symboliques sont impliqués):
cd /tmp mkdir foo ln -s foo bar find /tmp/foo -name foo find /tmp/bar -name foo
Dans votre cas, les deux appels donneraient le même résultat qui pourrait être (plus) déroutant. Vous pouvez utiliser -mindepth 1
si vous souhaitez ignorer les points de départ (peut être non-POSIX).
(gnu) find montre toutes les correspondances trouvées dans le path fourni à la command car il commence sa comparaison avec les arguments de la command line, descendant plus profondément dans la structure de directory à partir de là ( -maxdepth 0
confine les tests au niveau de base ou aux arguments de la command line seulement, alors que -mindepth 1
ignore les arguments de la command line comme l'explique l' man find
). C'est la raison pour laquelle find /tmp/foo -name 'foo'
donnera une correspondance même si le directory lui-même est vide.
find . -name 'foo'
find . -name 'foo'
d'autre part ne donnera aucun résultat parce que .
(dot) est un file spécial qui agit comme un lien vers le même inode que le file /tmp/foo
. Il s'agit d'un nom de file séparé et non d'un lien symbolique ou d'une expression soumise à l'expansion du nom de domaine par le shell. Par conséquent, le premier test appliqué par find aux arguments de la command line dans l'exemple donné ne montre aucune correspondance, puisque .
ne correspond en effet pas au model de nom défini dans -name 'foo'
. Ni /tmp/foo/.
car un test pour un model -name
est effectué sur le nom de base du path uniquement (voir man find
), qui est là encore .
.
Bien que ce comportement ne soit pas attendu ou n'apparaisse pas intuitif du sharepoint vue de l'user, il ne constitue pas un bug, mais correspond à la logique et à la fonctionnalité décrites dans les pages man et info de ( gnu) find.
J'ai essayé de commenter la réponse de Gilles, mais c'était trop long pour faire l'object d'un commentaire. Pour cette raison, je le mets en réponse à ma propre question.
L'explication de Gilles (et celle de Shevek aussi) est claire et logique. Le point key ici est que non seulement cherche à faire correspondre les noms de files pour les files à l'intérieur des paths donnés (récursivement), mais aussi, il essaie de faire correspondre le nom de base des paths donnés eux-mêmes.
D'autre part, y a-t-il une preuve que c'est la façon dont la find
est supposée fonctionner, plutôt que d'être un bug? À mon avis, ce serait mieux si cela ne rend pas les résultats incohérents pour la find .
et find ABSOLUTE-PATH
parce que l'incohérence est toujours source de confusion et pourrait gaspiller beaucoup de time au développeur à essayer de comprendre «ce qui n'allait pas». Dans mon cas, j'écrivais un script, et le path était pris d'une variable. Donc, pour que mon script fonctionne correctement, je peux écrire find $path/. -name 'pattern'
find $path/. -name 'pattern'
.
Finalement, je pense que l'obtention de résultats cohérents pour find
peut être obtenue en substituant toujours le .
avec le directory courant avant de continuer.
Il n'y a pas d'object nommé foo
dans le directory où vous avez démarré la search relative.
Vous avez raison en supposant que gfind
est gfind
quand il signale /tmp/foo
en utilisant le nom absolu comme directory de départ.
Gfind
a divers écarts par rapport à la norme, il semble que vous en avez trouvé un autre. Lorsque vous aimez une solution plus standard, je recommand sfind
qui fait partie des schilytools
.
-name
s'applique aux résultats de search d'annuaire. Aucun des deux cas mentionnés ne renvoie une input de directory foo
partir d'une opération readdir()
.