Bash Alias - 优先/隐藏(/隐藏/失败)

Bash Alias - 优先/隐藏(/隐藏/失败)

我在 .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 对第一种方法的评论)

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

或者,

  1. 同样,您可以在其他别名中通过添加反斜杠 '' 前缀来转义别名(也可以在命令行上执行此操作),例如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

附录

跑步的时候就不一样了lscRlscR扩展到:

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.

相关内容