奇怪的bash别名扩展

时间:2014-09-28 17:04:24

标签: bash recursion alias

我有一堆函数和一些别名。我从未想到的是这两个问题:

export EDITOR="emacsclient -t"
alias vi='$EDITOR'
alias pa='ps ax | egrep -i '

当我进入

pa vi

我得到了

egrep: invalid option -- 't'
显然," vi"当在另一个别名内时,即使它不在行的开头,也会被扩展。为什么这样,我该怎么办?

要仔细检查,请:

ps ax | egrep vi

正确执行。     bash --version     GNU bash,版本4.3.11(1)-release(x86_64-pc-linux-gnu)

1 个答案:

答案 0 :(得分:8)

你偶然发现了一个鲜为人知的shell编程问题。

通常,vi不会在该上下文中进行别名扩展,因为alias扩展仅适用于命令中的第一个单词(环境变量赋值除外)。但是,正如bash manual

所示
  

如果别名值的最后一个字符为空,则还会检查别名后面的下一个命令字的别名扩展。

单词不能跨越别名及其周围的文本,因此最后不需要空格:

alias pa='ps ax | egrep -i '

如果您将其更改为:

alias pa='ps ax | egrep -i'
事情将按预期发挥作用。但是你应该使用shell functions而不是别名;功能更强大,更不古怪,同样快。

注意:对于那些寻找更多证据表明bash是错误的人,我必须补充一点,以空白结尾的别名的特殊行为来自Posix规范,因此在任何一致的shell上都是相同的:

  

如果替换单词的别名的值以<blank>结尾,则shell应检查下一个命令字是否有别名替换;此过程将继续,直到找到不是有效别名的单词或别名值不以<blank>结尾。 (XSH,§2.3.1)