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

Why does shell builtin colon command ":" after variable assignment on same line cause empty string value to be assigned?

如果我在赋值后添加 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.

: (a colon)
: [arguments]
Do nothing beyond expanding arguments and performing redirections. The return status is zero.
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html

: 是 returns 成功的内置命令(true 的 shorthand 版本)。

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

所以当你 运行:

MyVar1='my var 1'  : colon comment here

你是:

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

the spec 中描述了此行为:

A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.

...

If no command name results, variable assignments shall affect the current execution environment. Otherwise, the variable assignments shall be exported for the execution environment of the command and shall not affect the current execution environment (except for special built-ins).

正如评论中指出的(谢谢!),: is one of the special built-ins,这意味着在符合标准的 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