Bashrc 无法再使用 && 或 ; 链接命令

Bashrc 无法再使用 && 或 ; 链接命令

你们是我最后的依靠。

我有一个包含各种命令的 bashrc 文件。其中很多命令都是这个命令的变体

alias test='
    test1 && test2
'
alias test1='
    echo "i hope" && \
    echo "this works"
'
alias test2='
    echo "because" && \
    echo "it annoys the hell out of me"
'

几天前,这个功能一直有效。从那时起,我就遇到了以下错误

$ test
i hope
this works
bash: syntax error near unexpected token `&&'

无论我使用&&还是;。命令 test1 和 test2 单独工作时均按预期运行,但我无法再将它们串联起来。我的 shell 是 bash,我让几位同事查看过它,但没人知道哪里出了问题。

$ echo $SHELL
/bin/bash

我是不是漏掉了什么?以前这些功能都管用,现在突然就不管用了,这很奇怪。

答案1

别名用文本替换文本。没有逻辑,只有文本替换。对于你的情况,请考虑使用 shell 函数。请参阅在 Bash 中,何时使用别名,何时使用脚本,何时编写函数?

Bash 扩展 后test,会扩展test1test2。这里没问题,这种多级扩展是允许的。但由于替换是纯文本的,因此所有字符都很重要。在一个定义中看似无害的字符可能会改变最终结果的逻辑,因为最终解释的是最终结果。

您的test扩展为:


    test1 && test2

然后扩展为:


    
    echo "i hope" && \
    echo "this works"
 && …

其中表示test2扩展到什么(与问题无关)。只有这样才能解释结果。

后面的换行符"it works"是 扩展后的最后一个字符test1。它是未转义的,它终止前面的命令。&&下一行中的 是意外的。

如果没有那个麻烦的换行符,情况就会有所不同:

alias test1='
    echo "i hope" && \
    echo "this works"'

或者如果它被转义了:

alias test1='
    echo "i hope" && \
    echo "this works"\
'

我相信我已经解释了这个问题并“解决”了它。不过我认为正确的做法是不要这样使用别名. 别名使用别名来构建一些逻辑应该被函数调用函数所取代。别名不是为了构建逻辑

如果test1test2是正常工作的 shell 函数(我的意思是每个函数都可以独立工作),那么表达式test1 && test2将按预期工作,无论定义中的换行符如何test1。这将起作用,因为表达式的逻辑将在执行test1和(可选)之前确定。在别名和在 shell 尝试确定逻辑之前展开的test2情况下(如我们所见),它们会影响逻辑。test1test2

这不仅仅与换行符有关。执行以下示例:

alias foo='echo 1; echo 2'
false && foo

如果您不知道foo是别名(或者您知道,但不知道别名的工作原理),那么您会期望foofalse && foo整体省略。 不,echo 2将被执行。 这是因为最终命令是false && echo 1; echo 2并且其逻辑与您预期的不同。

“等效” shell 函数表现更好。以下代码片段foo根本不会执行,正如您所期望的那样false && foo

unalias foo
foo() { echo 1; echo 2; }
false && foo

对我来说,理解别名愚蠢地取代文字与文字是一个转折点。我所有与别名有关的麻烦都源于没有意识到这个基本事实。


另外要注意的test标准命令. 你不应该创建别名或名为的函数test,除非你的目标是故意替换标准test

相关内容