GNU/Linux >> Tutoriels Linux >  >> Linux

Le Résultat De Ls * , Ls ** Et Ls *** ?

Je sais utiliser la commande ls listera tous les répertoires. Mais qu'est-ce que le ls * commande faire ? Je l'ai utilisé et il répertorie simplement les répertoires. Est-ce que l'étoile devant ls signifie à quelle profondeur il listera les répertoires ?

Réponse acceptée :

ls répertorie les fichiers et le contenu des répertoires qui lui sont transmis en tant qu'arguments, et si aucun argument n'est donné, il répertorie le répertoire courant. On peut également lui passer un certain nombre d'options qui affectent son comportement (voir man ls pour plus de détails).

Si ls reçoit un argument appelé * , il recherchera un fichier ou un répertoire appelé * dans le répertoire courant et listez-le comme n'importe quel autre. ls ne traite pas le * caractère d'une autre manière que toute autre.

Cependant si ls * est un shell ligne de commande, c'est-à-dire code dans le langage d'un shell Unix , alors le shell développera ce * selon son globbing (également appelé Génération de noms de fichiers ou Développement du nom de fichier/chemin d'accès ) règles.

Bien que différents shells prennent en charge différents opérateurs de globalisation, la plupart d'entre eux s'accordent sur le plus simple * . * comme un motif signifie n'importe quel nombre de caractères, donc * en tant que glob développera la liste des fichiers dans les répertoires actuels qui correspondent à ce modèle. Il y a une exception cependant qu'un point de tête (. ) dans un nom de fichier doit correspondre explicitement, donc * s'étend en fait à la liste des fichiers et répertoires ne commençant pas par . (par ordre lexical).

Par exemple, si le répertoire courant contient les fichiers appelés . , .. , .foo , -l et foo bar , * sera étendu par le shell à deux arguments à passer à ls :-l et foo bar , ce sera donc comme si vous aviez tapé :

ls -l "foo bar"

ou

'ls' "-l" foo bar

Ce sont trois façons d'exécuter exactement la même commande. Dans les 3 cas, le ls commande (qui sera probablement exécutée depuis /bin/ls à partir d'une recherche de répertoires mentionnés dans $PATH ) recevront ces 3 arguments :"ls", "-l" et "foo bar".

Incidemment, dans ce cas, ls traitera le premier (à proprement parler second ) un en option.

Maintenant, comme je l'ai dit, différents shells ont différents opérateurs de globalisation. Il y a quelques décennies, zsh introduit le **/ opérateur¹ qui signifie correspondre à n'importe quel niveau de sous-répertoires, abréviation de (*/)# et ***/ qui est identique sauf qu'il suit les liens symboliques tout en descendant les répertoires.

Il y a quelques années (juillet 2003, ksh93o+ ), ksh93 a décidé de copier ce comportement mais a décidé de le rendre facultatif et ne couvrait que le ** cas (pas *** ). Aussi, tandis que ** seul n'était pas spécial dans zsh ² (signifiait simplement la même chose que * comme dans les autres shells traditionnels depuis ** signifie n'importe quel nombre de caractères suivi de n'importe quel nombre de caractères), dans ksh93, ** signifiait la même chose que **/* (donc tout fichier ou répertoire en dessous de l'actuel (hors fichiers cachés)³.

bash copié ksh93 quelques années plus tard (février 2009, bash 4.0), avec la même syntaxe mais une différence fâcheuse :le ** de bash était comme zsh c'est *** , c'est-à-dire qu'il suivait des liens symboliques lors de la récurrence dans des sous-répertoires, ce qui n'est généralement pas ce que vous voulez qu'il fasse et peut avoir des effets secondaires désagréables. Il a été partiellement corrigé dans bash-4.3 en ce sens que les liens symboliques étaient toujours suivis, mais la récursivité s'est arrêtée là. Il a été entièrement corrigé dans la version 5.0.

yash ajouté ** dans la version 2.0 en 2008, activé avec le extended-glob option. Son implémentation est plus proche de zsh est dans ce ** seul n'est pas spécial. Dans la version 2.15 (2009), il a ajouté *** comme dans zsh et deux de ses propres extensions :.** et .*** pour inclure les répertoires cachés lors de la récurrence (en zsh , le D qualificatif global (comme dans **/*(D) ) prendra en compte les fichiers et répertoires cachés, mais si vous souhaitez uniquement parcourir les répertoires cachés sans développer les fichiers cachés, vous avez besoin de ((*|.*)/)#* ou **/[^.]*(D) ).

Connexes :La simulation de circuit d'écrêtage produit un résultat inattendu ?

La coquille de poisson prend également en charge ** . Comme la version précédente de bash , il suit les liens symboliques lors de la descente de l'arborescence des répertoires. Dans ce shell cependant **/* n'est pas identique à ** . ** est plus une extension de * qui peut s'étendre sur plusieurs répertoires. En fish , **/*.c correspondra à a/b/c.c mais pas a.c , tandis que a**.c correspondra à a.c et ab/c/d.c et zsh c'est **/.* par exemple doit être écrit .* **/.* . Là, *** est compris comme ** suivi de * donc identique à ** .

tcsh également ajouté un globstar option dans V6.17.01 (mai 2010) et prend en charge à la fois ** et *** à la zsh .

Donc en tcsh , bash et ksh93 , (lorsque l'option correspondante est activée (globstar )) ou fish , ** développe tous les fichiers et répertoires sous l'actuel, et *** est identique à ** pour fish , un lien symbolique traversant ** pour tcsh avec globstar , et identique à * dans bash et ksh93 (bien qu'il ne soit pas impossible que les futures versions de ces shells traversent également des liens symboliques).

Ci-dessus, vous aurez remarqué la nécessité de s'assurer qu'aucune des extensions n'est interprétée comme une option. Pour cela, vous feriez :

ls -- *

Ou :

ls ./*

Il y a quelques commandes (peu importe pour ls ) où la seconde est préférable puisque même avec le -- certains noms de fichiers peuvent être traités spécialement. C'est le cas de - pour la plupart des utilitaires de texte, cd et pushd et les noms de fichiers contenant le = caractère pour awk par exemple. Préfixe ./ à tous les arguments enlève leur signification particulière (au moins pour les cas mentionnés ci-dessus).

Il convient également de noter que la plupart des shells ont un certain nombre d'options qui affectent le comportement global (comme si les fichiers de points sont ignorés ou non, l'ordre de tri, que faire s'il n'y a pas de correspondance…), voir aussi le $FIGNORE paramètre dans ksh

Aussi, dans chaque shell sauf csh , tcsh , fish et zsh , si le motif global ne correspond à aucun fichier, le modèle est passé en tant qu'argument non développé, ce qui provoque une confusion et éventuellement des bogues. Par exemple, s'il n'y a pas de fichier non caché dans le répertoire courant

ls *

Appelera en fait ls avec les deux arguments ls et * . Et comme il n'y a pas de fichier du tout, donc aucun ne s'appelle * soit, vous verrez un message d'erreur de ls (pas le shell) comme :ls: cannot access *: No such file or directory , qui est connu pour faire croire aux gens qu'il s'agissait de ls qui étendait en fait les globs.

Le problème est encore pire dans des cas comme :

rm -- *.[ab]

S'il n'y a pas de *.a ni *.b fichier dans le répertoire courant, vous risquez de finir par supprimer un fichier appelé *.[ab] par erreur (csh , tcsh , et zsh signalerait une pas de correspondance erreur et n'appellerait pas rm (et fish ne prend pas en charge le [...] caractères génériques)).

Si vous voulez passer un * littéral à ls , vous devez citer ce * caractère d'une certaine manière comme dans ls * ou ls '*' ou ls "*" . Dans les shells de type POSIX, le globbing peut être complètement désactivé en utilisant set -o noglob ou set -f (ce dernier ne fonctionne pas dans zsh sauf en sh /ksh émulation).

Connexe :Php :mysql_field_seek — Définit le pointeur de résultat sur un décalage de champ spécifié

.


Linux
  1. Comment vérifier la version du système d'exploitation et de Linux

  2. Trouvez les fichiers et répertoires les plus volumineux sous Linux

  3. Quelle est la différence entre Sudo Su - et Sudo Su - ?

  4. Obtenir le complément du résultat d'une commande Ls ?

  5. Quelle est la différence entre ls et l ?

Linux sur le mainframe :hier et aujourd'hui

Quelle est la différence entre InnoDB et MyISAM ?

La commande Linux Sed :utilisation et exemples

Quelle est la différence entre Linux et Unix ?

Et la meilleure distribution de 2019 est ...

Quelle est la différence entre unlink et rm ?