- lors de la spécification
ls --directory a*
, ne lister que les répertoires commençant para*
- MAIS il répertorie les fichiers ET les répertoires commençant par
a
Questions :
- Où pourrais-je trouver de la documentation à ce sujet, autre que
man
etinfo
où je pense avoir bien regardé? - cela fonctionne-t-il uniquement dans BASH?
echo a*
vous indiquera également les fichiers commençant para
(le cas échéant). Juste pour que ce soit plus clair, ce n'est pasls
cela qui se fait, mais la bashRéponses:
La syntaxe
a*
et*a*
est implémentée par le shell, pas par lals
commande.Quand vous tapez
à l'invite de votre shell, celui-ci se développe
a*
en une liste de tous les fichiers existants dans le répertoire en cours dont le nom commence para
. Par exemple, il peut être étendua*
à la séquencea1 a2 a3
et transmis comme arguments àls
. Lals
commande elle-même ne voit jamais le*
personnage; il ne voit que les trois argumentsa1
,a2
eta3
.Aux fins d'expansion des caractères génériques, "fichiers" fait référence à toutes les entités du répertoire actuel. Par exemple, il
a1
peut s'agir d'un fichier normal, d'a2
un répertoire et d'a3
un lien symbolique. Ils ont tous des entrées de répertoire, et l'extension générique du shell ne tient pas compte du type d'entité auquel ces entrées font référence.Pratiquement tous les shells rencontrés (bash, sh, ksh, zsh, csh, tcsh, ...) implémentent des caractères génériques. Les détails peuvent varier, mais la syntaxe de base consistant à faire
*
correspondre zéro ou plusieurs caractères et à faire?
correspondre n'importe quel caractère est raisonnablement cohérente.Pour bash en particulier, cela est documenté dans la section "Développement du nom de fichier" du manuel bash; lancez
info bash
et cherchez "extension de nom de fichier", ou voyez ici .Le fait que cela soit fait par le shell, et non par des commandes individuelles, a des conséquences intéressantes (et parfois surprenantes). La meilleure chose à ce sujet est que la gestion des caractères génériques est cohérente pour (presque) toutes les commandes; Si le shell ne le faisait pas, certaines commandes ne le dérangeraient inévitablement pas, et d'autres le feraient de manières légèrement différentes que l'auteur pensait "meilleures". (Je pense que le shell de commande Windows a ce problème, mais je ne le connais pas suffisamment pour commenter davantage.)
D'autre part, il est difficile d'écrire une commande pour renommer plusieurs fichiers. Si vous écrivez:
il échouera probablement car il
*.log.bak
est développé en fonction des fichiers déjà présents dans le répertoire en cours. Certaines commandes font ce genre de choses, mais elles doivent utiliser leur propre syntaxe pour spécifier comment les fichiers doivent être renommés. Certaines commandes (telles quefind
) peuvent créer leur propre développement générique. vous devez citer les arguments pour supprimer l'expansion du shell:Le développement des caractères génériques du shell repose entièrement sur la syntaxe de l'argument de ligne de commande et de l'ensemble des fichiers existants. Il ne peut pas être affecté par le sens de la commande. Par exemple, si vous souhaitez déplacer tous les
.log
fichiers vers le répertoire parent, vous pouvez taper:Si vous oubliez le
..
:et il se trouve qu'il y a exactement deux
.log
fichiers dans le répertoire courant, il va s'étendre à:qui va renommer
one.log
et clobbertwo.log
.EDIT : Et après 52 votes positifs, un accept et un badge Guru, je devrais peut-être répondre à la question dans le titre.
L' option
-d
ou ne dit pas de ne lister que les répertoires. Il lui dit de lister les répertoires comme eux-mêmes, pas leur contenu. Si vous donnez un nom de répertoire comme argument , par défaut, le contenu du répertoire sera répertorié , car c'est généralement ce qui vous intéresse. L' option lui dit de ne répertorier que le répertoire lui-même. Cela peut être particulièrement utile lorsqu'il est combiné avec des caractères génériques. Si vous tapez:--directory
ls
ls
-d
ls
vous donnera une longue liste de chaque fichier dont le nom commence para
, et du contenu de chaque répertoire dont le nom commence para
. Si vous voulez juste une liste des fichiers et des répertoires, une ligne pour chacun, vous pouvez utiliser:qui équivaut à:
Rappelez-vous à nouveau que la
ls
commande ne voit jamais le*
personnage.Quant à savoir où cela est documenté,
man ls
vous montrera la documentation de lals
commande sur n'importe quel système de type Unix. Sur la plupart des systèmes basés sur Linux, lals
commande fait partie du paquet GNU coreutils; si vous avez lainfo
commande, vous devriezinfo ls
ouinfo coreutils ls
vous fournir une documentation plus complète et plus définitive. D'autres systèmes, tels que MacOS, peuvent utiliser différentes versions de lals
commande et ne pas en disposerinfo
; pour ces systèmes, utilisezman ls
. Etls --help
affichera un message d'utilisation relativement court (117 lignes sur mon système) si vous utilisez la mise en œuvre GNU coreutils.Et oui, même les experts doivent consulter la documentation de temps en temps. Voir aussi cette blague classique .
la source
a*
étend la liste de tous les fichiers du répertoire actuel dont le nom commence para
.ls subdir/a*
echo
il faut. Donc, si vous voulez savoir ce qui se passe quand vous le faitesls a*
, exécutez d'abordecho ls a*
echo a*
... la coquille ne fait que glob l'expansionshopt -s failglob
provoque le même comportement. Définirnullglob
mais nefailglob
provoque pas , par exemple,*nosuchfile*
pour développer une chaîne vide.Voir la réponse de Keith Thompson; mais pour expliquer pourquoi
ls --directory a*
affiche les fichiers et les répertoires: L'--directory
option ne supprime pas les fichiers autres que des répertoires. Au lieu de cela, il répertorie les répertoires en tant que tels, alors qu'il listerait autrement leur contenu. Exemple:la source
-F
optionPour être très explicite, il est documenté dans la page de manuel ls (1) :
-d, --directory liste les entrées du répertoire au lieu du contenu, et ne déréférence pas les liens symboliques
pour être juste, "entrées au lieu de contenu" pourrait probablement être plus explicatif:
la source
Globbing
Comme cela a été expliqué, le développement de
*
(et les développements similaires) s'appelleglob
bing dans le jargon Unix et est généralement une fonctionnalité du processeur de commande (appelé le "shell" dans le langage Unix). Donc globbing peut être utilisé dans beaucoup d'autres endroits aussi; tapezman 7 glob
sur le shell d'une distribution Linux classique (ou voyez ceci ) pour en savoir plus surglob
bing.Au début, Unix
glob
était en réalité implémenté par un programme séparé appelé/etc/glob
(reportez-vous à la page 10 de cet ancien manuel UNIX pour la documentation correspondante). De nos jours, il s'agit d'une routine de code fournie par les bibliothèques de codes et couramment utilisée par les shells. Source : Wikipedia .Répertoires
Pourquoi les
ls -d
listes de fichiers ainsi que les répertoires ...La
ls
page de manuel explique pourquoi cela se produit, mais avec une explication très concise. Donc, voici une tentative d'explication élargie:Par défaut,
ls
répertorie le contenu des répertoires quand on leur donne leur nom, et fera la même chose pour les liens symboliques vers les répertoires. L'-d
option signifie "lorsque le ou les noms de répertoire (s) sont donnés" (qui peut également être donné implicitement parglob
bing) , affiche uniquement les _name_s du / des répertoire (s), mais pas leur contenu. De même, lorsque le nom (ou les liens) des liens symboliques vers les répertoires sont fournis (explicitement ou implicitement ) , affichez le nom du fichier du lien symbolique, pas le contenu du répertoire auquel il fait référence.L'
-d
option n'a rien à voir, autant que je sache, avec quels éléments sont listés; cela peut être fait (source: ici ) avecfind
, comme suit:find . -maxdepth 1 -type d
. Je ne suis pas sûr s'il existe un bon moyen de le faire uniquement avec GNUls
. Voici quelques exemples d'utilisation de lafind
commande.Donc, pour résumer: Par défaut,
ls
affiche le contenu des répertoires lorsque leur nom de chemin est donné.-d
modifie ce comportement en affichant uniquement le nom du répertoire lui-même, comme ce serait le cas pour un fichier standard.la source
La documentation n'indique pas qu'elle répertorie uniquement les entrées de répertoire, mais plutôt quand elle
ls
reçoit un nom de répertoire, elle répertorie l'entrée dir au lieu de son contenu. Le meilleur moyen de comprendre est par exemple:la source
La documentation fait partie du shell . En particulier, le shell effectue diverses expansions et substitutions dans un ordre particulier avant d'exécuter une commande.
La séquence d’ expansion de mots pour un shell compatible Bourne est
Donc, la
ls
commande ne voit même pas les*
caractères, les arguments sont déjà développés avec tous les fichiers correspondant aua*
motif glob. Ceci est différent de Windows, où chaque commande nécessitant une suppression de nom de fichier doit implémenter cette fonctionnalité elle-même.la source
Le mot clé dont vous avez besoin (
man bash
) est "Expansion du nom de chemin".la source