Bash Alias - Vorrang / Schatten (/ Verstecken / Versagen)
Ich habe einige Aliase (in dieser Reihenfolge) in .bashrc eingerichtet:
alias ls="lsc"
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Bestätigung aliasnach dem Sourcing:
alias ls='lsc'
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Ich kann den neu aliased lsgut ausführen , und er verkettet sich mit dem lsc-Alias und führt dann den Befehl aus, der dem lsc-Alias zugeordnet ist. Ich kann auch laufen lscRund es funktioniert wie erwartet.
Wenn ich versuche lsc, mich selbst zu betreiben , bekomme ich:
$ lsc
lsc: command not found
Irgendeine Idee, warum die Shell den lsc-Alias in diesem Szenario zu beschatten / zu verbergen scheint? (Mir ist klar, dass es sinnlos ist, 'lsc' auszuführen, wenn ich nur 'ls' ausführen kann, um hier das gleiche Ergebnis zu erzielen, aber ich versuche, das Verhalten der Shells in diesem Szenario zu verstehen.)
BEARBEITEN: Die folgenden Problemumgehungen für das (Bash-) Shell-Verhalten in den Fragenantworten.
Auf die ursprüngliche Frage wurden einige wirklich hilfreiche Antworten gegeben. Um das in den Antworten erläuterte Erweiterungsverhalten kurzzuschließen, scheint es mindestens zwei Möglichkeiten zu geben, einen zweiten Alias daran zu hindern, einen Befehl zu erweitern, den Sie bereits als Alias verwendet haben. Wenn Sie beispielsweise alias cmd='cmd --stuff'einen nativen Befehl namens überschreiben cmd, können Sie verhindern, dass der 'cmd'-Alias anstelle des nativen cmdin anderen Aliasnamen verwendet wird, indem:
(Dank an wjandreas Kommentar für diesen ersten Ansatz)
- Präfix
cmdmit 'Befehl' im anderen Alias, zalias other-cmd-alias='command cmd --other-stuff'
oder,
- In ähnlicher Weise können Sie Aliase (wie auch in der Befehlszeile) innerhalb anderer Aliase maskieren, indem Sie einen Backslash '' voranstellen, z
alias other-cmd-alias='\cmd --other-stuff'.
Antworten
Bash erlaubt es Aliasen, Aliase zu enthalten, verfügt jedoch über einen integrierten Schutz gegen Endlosschleifen. In Ihrem Fall lscerweitert bash beim Eingeben zuerst den Alias auf:
ls -Flatr --color=always
Da lses sich auch um einen Alias handelt, erweitert bash ihn auf:
lsc -Flatr --color=always
lscist ein Alias, aber Bash weigert sich vernünftigerweise, ihn ein zweites Mal zu erweitern . Wenn es ein Programm mit dem Namen gab lsc, würde bash es ausführen. Aber das gibt es nicht und deshalb bekommst du command not found.
Nachtrag
Beim Laufen ist es anders lscR. lscRerweitert sich zu:
ls -FlatrR --color=always
Da lses sich um einen Alias handelt, wird dieser erweitert auf:
lsc -FlatrR --color=always
Da lsces sich um einen Alias handelt, wird dieser erweitert auf:
ls -Flatr --color=always -FlatrR --color=always
Da lsbash bereits einmal erweitert wurde, weigert sich bash, es ein zweites Mal zu erweitern . Da ein realer Befehl namens lsexistiert, wird er ausgeführt.
Geschichte
Wie Schily in den Kommentaren bemerkte , hat bash das Konzept übernommen, einen Alias nicht ein zweites Mal von ksh zu erweitern .
Beiseite
Aliase sind nützlich, aber nicht sehr mächtig. Wenn Sie versucht sind, mit einem Alias etwas Komplexes zu tun, z. B. eine Argumentersetzung, tun Sie dies nicht. Verwenden Sie stattdessen eine Shell-Funktion.
Aus dem Bash-Handbuch :
Das erste Wort des Ersatztextes wird auf Aliase getestet, aber ein Wort, das mit einem zu erweiternden Alias identisch ist, wird nicht ein zweites Mal erweitert. Dies bedeutet, dass man beispielsweise einen Alias
lsfür "ls -F" verwenden kann und Bash nicht versucht, den Ersatztext rekursiv zu erweitern.
Im lsAlias lswird auf lscund dann wieder auf erweitert ls -Flatr --color=always, und dort stoppt die Alias-Erweiterung, da sie lsursprünglich erweitert wurde. Der Befehl läuft also einwandfrei und wird lsnun in einen externen Befehl aufgelöst.
Im lscAlias lscwird erweitert ls -Flatr --color=alwaysund wird dann lserweitert lscund dort stoppt die Alias-Erweiterung, da sie lscursprünglich erweitert wurde. Der Befehl schlägt also fehl, da bash keinen anderen kennt lsc.