首页 > 解决方案 > shell 别名什么时候生效?

问题描述

我阅读了 POSIX 规范中的“别名替换”部分,但似乎无法弄清楚这一点。

考虑这两个脚本:

alias x="echo hello"
x

if true; then
    alias x="echo hello"
    x
fi

在我测试的两个 shell(dash 和 zsh)中,它们都有相同的行为。第一个脚本打印“hello”,第二个脚本产生错误,因为x它不是命令。

complete_command从这些测试来看,别名似乎在 POSIX 语法中 next 的开头生效。如果是这种情况,它在 POSIX 规范中的位置是什么?

标签: shellshposixalias

解决方案


请参阅POSIX 规范以了解别名替换

别名替换发生在解析期间(或至少在评估之前)。因为整个if语句是一个一次性解析的复合命令,这意味着在前面的命令实际定义别名之前x进行别名替换,并且只能被在语句之前在完整命令行上定义的别名替换。aliasif

例如,考虑代码

alias x="echo hello"
if true; then
    x
fi

解析后,转换为代码

alias x="echo hello"
if true; then
    echo hello
fi

就是实际执行的代码。

现在考虑

alias x="echo hello"
if true; then
    alias x="echo goodbye"
    x
fi
x

同样,在if解析语句时,x定义为echo hello,而不是echo goodbye。但是if解析执行之后,x已经重新定义了,所以上面的等价于

alias x="echo hello"
if true; then
    alias x="echo goodbye"
    echo hello
fi
echo goodbye

推荐阅读