为什么 shell 内置冒号命令在同一行上的变量赋值后":"会导致分配空字符串值?



如果我在赋值后添加colon(:(内置shell命令,变量将被分配给空字符串(""(。 为什么它表现得那样? 我预计它不会有任何效果。

    set -vx
    MyVar1='my var 1'  : colon comment here  # *** !!! This gets assigned to empty string!!!
    MyVar2='my var 2'  # hash comment here; this is fine
    echo "MyVar1 = [$MyVar1]"  # EXPECTED: 'my var 1'; ACTUAL: '' (empty string).  Why?
    echo "MyVar2 = [$MyVar2]"  # As expected.

(冒号(
:[参数]
除了展开参数和执行重定向之外,不执行任何操作。返回状态为零。
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html

>:是一个成功返回的内置命令(true的速记版本(。

当您在与命令相同的行上执行变量赋值时,赋值仅在命令的持续时间内有效(这通常用于运行设置了临时环境变量的命令(。

因此,当您运行时:

MyVar1='my var 1'  : colon comment here

你是:

  • 运行命令:
  • 传递参数coloncommenthere(这些参数被命令删除(
  • 使用临时变量赋值MyVar1='my var 1'(这对命令没有影响(

规范中描述了此行为:

"简单命令"是一系列可选的变量赋值和重定向,按任何顺序排列,可以选择后跟单词和重定向,由控制运算符终止。

如果没有命令名称结果,变量赋值将影响当前执行环境。否则,应针对命令的执行环境导出变量赋值,不影响当前执行环境(特殊内置除外(。

正如评论中指出的(谢谢!(,:特殊的内置之一,这意味着在符合标准的 shell 中,赋值应该影响当前的执行环境。默认情况下,Bash 在这个意义上不符合规范,尽管您可以通过将其作为 sh 调用(在它是默认 shell 的系统上(或使用 bash --posix

来实现:
$ bash -c 'foo=bar :; echo $foo'
$ sh -c 'foo=bar :; echo $foo'
bar
$ bash --posix -c 'foo=bar :; echo $foo'
bar

最新更新