Alias bash - Priorité / Ombrage (/ masquage / échec)
J'ai quelques alias configurés (dans cet ordre) dans .bashrc:
alias ls="lsc"
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Les confirmer avec alias
après sourcing:
alias ls='lsc'
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Je peux très bien exécuter le nouvel aliasé ls
, et il se connecte à l'alias lsc, puis exécute la commande associée à l'alias lsc. Je peux aussi courir lscR
et cela fonctionne comme prévu.
Si j'essaye de fonctionner tout lsc
seul, j'obtiens:
$ lsc
lsc: command not found
Une idée de la raison pour laquelle le shell semble masquer / masquer l'alias lsc dans ce scénario? (Je me rends compte qu'il est inutile d'exécuter 'lsc' alors que je peux simplement exécuter 'ls' pour obtenir le même résultat ici, mais j'essaie de comprendre le comportement des shells dans ce scénario).
EDIT: solutions de contournement ci-dessous pour le comportement du shell (bash) fourni dans les réponses aux questions.
Des réponses vraiment utiles ont été apportées à la question initiale. Afin de court-circuiter le comportement d'expansion qui est expliqué dans les réponses, il semble y avoir au moins deux façons d'empêcher un deuxième alias d'essayer d'étendre une commande que vous avez déjà aliasée. Par exemple, si vous avez alias cmd='cmd --stuff'
qui remplace une commande native appelée cmd
, vous pouvez empêcher que l'alias 'cmd' ne soit utilisé à la place du natif cmd
dans d'autres alias, en:
(merci au commentaire de wjandrea pour cette première approche)
- préfixer
cmd
avec 'commande' dans l'autre alias, par exemplealias other-cmd-alias='command cmd --other-stuff'
ou,
- De même, vous pouvez échapper les alias (comme vous pouvez également le faire sur la ligne de commande), dans d'autres alias en préfixant avec une barre oblique inverse '', par exemple
alias other-cmd-alias='\cmd --other-stuff'
.
Réponses
Bash permet aux alias de contenir des alias, mais il dispose de protections intégrées contre les boucles infinies. Dans votre cas, lorsque vous tapez lsc
, bash développe d'abord l'alias en:
ls -Flatr --color=always
Puisqu'il ls
s'agit également d'un alias, bash l'étend à:
lsc -Flatr --color=always
lsc
est un alias mais, de manière tout à fait raisonnable, bash refuse de l'étendre une seconde fois . S'il y avait un programme nommé lsc
, bash l'exécuterait. Mais, il n'y en a pas et c'est pourquoi vous obtenez command not found
.
Addenda
C'est différent quand lscR
s'exécute. lscR
s'étend à:
ls -FlatrR --color=always
Puisqu'il ls
s'agit d'un alias, cela s'étend à:
lsc -FlatrR --color=always
Puisqu'il lsc
s'agit d'un alias, cela s'étend à:
ls -Flatr --color=always -FlatrR --color=always
Puisqu'il ls
a déjà été étendu une fois, bash refuse de l'étendre une seconde fois . Puisqu'une vraie commande appelée ls
existe, elle est exécutée.
L'histoire
Comme l'a noté Schily dans les commentaires, bash a emprunté le concept de ne pas développer un alias une deuxième fois à ksh .
De côté
Les alias sont utiles mais pas très puissants. Si vous êtes tenté de faire quelque chose de complexe avec un alias, comme la substitution d'argument, ne le faites pas; utilisez plutôt une fonction shell.
À partir du manuel bash :
Le premier mot du texte de remplacement est testé pour les alias, mais un mot identique à un alias en cours de développement n'est pas développé une deuxième fois. Cela signifie que l'on peut utiliser un alias
ls
sur "ls -F
", par exemple, et Bash n'essaye pas de développer récursivement le texte de remplacement.
Dans l' ls
alias, ls
est développé vers lsc
, puis de nouveau vers ls -Flatr --color=always
, et là, l'expansion de l'alias s'arrête, car elle ls
était initialement développée. Ainsi, la commande fonctionne correctement, ls
étant maintenant résolue en une commande externe.
Dans l' lsc
alias, lsc
est étendu à ls -Flatr --color=always
, puis ls
est maintenant développé vers lsc
et là, l'expansion de l'alias s'arrête, car elle lsc
était initialement développée. Donc, la commande échoue, car bash n'en connaît pas d'autre lsc
.