Bash Alias ​​- Vorrang / Schatten (/ Verstecken / Versagen)

Aug 17 2020

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)

  1. Präfix cmdmit 'Befehl' im anderen Alias, zalias other-cmd-alias='command cmd --other-stuff'

oder,

  1. 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

13 John1024 Aug 17 2020 at 11:58

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.

6 muru Aug 17 2020 at 12:00

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.