Bash 别名 - 优先级/阴影(/hiding/failing)

Chr*_*ris 7 bash

我在 .bashrc 中设置了一些别名(按此顺序):

alias ls="lsc"
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Run Code Online (Sandbox Code Playgroud)

alias采购后确认:

alias ls='lsc'
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
Run Code Online (Sandbox Code Playgroud)

我可以ls很好地运行新别名,它会链接到 lsc 别名,然后执行与 lsc 别名关联的命令。我也可以运行lscR,它按预期运行。

如果我尝试自己运行lsc,我会得到:

$ lsc
lsc: command not found
Run Code Online (Sandbox Code Playgroud)

知道为什么外壳在这种情况下似乎隐藏/隐藏了 lsc 别名吗?(我意识到当我可以在这里运行 'ls' 来获得相同的结果时运行 'lsc' 毫无意义,但我正在尝试了解这种情况下的 shell 行为)。

编辑:问题答案中提供的(bash)shell 行为的以下解决方法。

已经为原始问题提供了一些非常有用的答案。为了缩短答案中解释的扩展行为,似乎至少有两种方法可以防止第二个别名尝试扩展您已经使用别名的命令。例如,如果您有alias cmd='cmd --stuff'覆盖名为 的本机命令cmd,则可以通过以下方式防止使用“cmd”别名代替cmd其他别名中的本机命令:

(感谢 wjandrea 对第一种方法的评论)

  1. cmd在另一个别名中以“command”作为前缀,例如alias other-cmd-alias='command cmd --other-stuff'

或者,

  1. 同样,您可以通过在其他别名中添加反斜杠 '' 来转义别名(您也可以在命令行中执行),例如alias other-cmd-alias='\cmd --other-stuff'.

Joh*_*024 13

Bash 确实允许别名包含别名,但它具有针对无限循环的内置保护。在您的情况下,当您键入时lsc,bash 首先将别名扩展为:

ls -Flatr --color=always
Run Code Online (Sandbox Code Playgroud)

由于ls也是别名,bash 将其扩展为:

lsc -Flatr --color=always
Run Code Online (Sandbox Code Playgroud)

lsc是一个别名,但相当理智,庆典拒绝扩大它第二次。如果有一个名为 的程序lsc,bash 会运行它。但是,没有,这就是为什么你得到command not found.

附录

lscR跑的时候就不一样了。 lscR扩展为:

ls -FlatrR --color=always
Run Code Online (Sandbox Code Playgroud)

由于ls是别名,因此扩展为:

lsc -FlatrR --color=always
Run Code Online (Sandbox Code Playgroud)

由于lsc是别名,因此扩展为:

ls -Flatr --color=always -FlatrR --color=always
Run Code Online (Sandbox Code Playgroud)

既然ls已经扩大一次,庆典拒绝展开第二次。由于ls存在一个名为的实际命令,因此它会运行。

历史

正如Schily在评论中指出的那样,bash 借用了不从ksh再次扩展别名的概念。

在旁边

别名很有用,但不是很强大。如果你想用别名做一些复杂的事情,比如参数替换,不要;改用 shell 函数。


mur*_*uru 6

bash 手册

替换文本的第一个单词会测试别名,但与被扩展的别名相同的单词不会被第二次扩展。例如,这意味着可以ls将“ ls -F”作为别名,并且 Bash 不会尝试递归扩展替换文本。

ls别名中,ls扩展为lsc,然后再次扩展为ls -Flatr --color=always,并且别名扩展在那里停止,因为ls最初是被扩展的。因此,该命令运行良好,ls现在被解析为外部命令。

lsc别名,lsc扩大到ls -Flatr --color=always,然后ls被扩大到现在的lsc别名扩张停止,因为lsc本来正在扩大。因此,该命令失败,因为 bash 不知道任何其他lsc.