我在 .bashrc 中有一些别名设置(按此顺序):
alias ls="lsc"
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
采购后确认alias
:
alias ls='lsc'
alias lsc='ls -Flatr --color=always'
alias lscR='ls -FlatrR --color=always'
我可以很好地运行新的别名ls
,它会链接到 lsc 别名,然后执行与 lsc 别名关联的命令。我也可以运行lscR
并且它按预期运行。
如果我尝试lsc
自行运行,我会得到:
$ lsc
lsc: command not found
知道为什么 shell 在这种情况下似乎隐藏/隐藏了 lsc 别名吗? (我意识到,当我可以运行“ls”来获得相同的结果时,运行“lsc”是没有意义的,但我试图理解这种情况下的 shell 行为)。
编辑:以下问题答案中提供的(bash)shell 行为的解决方法。
对原始问题提供了一些非常有用的答案。为了短路答案中解释的扩展行为,似乎至少有两种方法可以阻止第二个别名,即尝试扩展您已经使用别名的命令。例如,如果您有alias cmd='cmd --stuff'
覆盖名为 的本机命令cmd
,则可以通过以下方式防止使用“cmd”别名来代替cmd
其他别名中的本机命令:
(感谢 wjandrea 对第一种方法的评论)
cmd
在另一个别名中添加“command”前缀,例如alias other-cmd-alias='command cmd --other-stuff'
或者,
- 同样,您可以在其他别名中通过添加反斜杠 '' 前缀来转义别名(也可以在命令行上执行此操作),例如
alias other-cmd-alias='\cmd --other-stuff'
。
答案1
Bash 确实允许别名包含别名,但它具有针对无限循环的内置保护。在您的情况下,当您输入 时lsc
,bash 首先将别名扩展为:
ls -Flatr --color=always
由于ls
也是一个别名,bash 将其扩展为:
lsc -Flatr --color=always
lsc
是一个别名,但相当明智的是,bash 拒绝将其扩展为第二次。如果有一个名为 的程序lsc
,bash 就会运行它。但是,没有,这就是为什么你得到command not found
。
附录
跑步的时候就不一样了lscR
。 lscR
扩展到:
ls -FlatrR --color=always
由于ls
是别名,因此扩展为:
lsc -FlatrR --color=always
由于lsc
是别名,因此扩展为:
ls -Flatr --color=always -FlatrR --color=always
由于ls
已经扩展过一次,bash拒绝扩展它第二次。由于存在名为 的真实命令ls
,因此会运行该命令。
历史
正如所指出的希利在评论中,bash 借用了不再次扩展别名的概念克什。
在旁边
别名很有用,但不是很强大。如果您想使用别名做一些复杂的事情,例如参数替换,请不要这样做;请改用 shell 函数。
答案2
从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
.