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

Rob*_*ark 7 bash shell sh variable-assignment built-in

如果在分配后添加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.
Run Code Online (Sandbox Code Playgroud)

:(冒号)
:[自变量]
除了扩展自变量和执行重定向之外,什么也不要做。返回状态为零。
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html

Tom*_*ech 10

:是可成功返回的内置命令(的简写版本true)。

当您在命令的同一行上进行变量分配时,该分配仅在命令持续时间内有效(通常用于运行设置了临时环境变量的命令)。

因此,当您运行时:

MyVar1='my var 1'  : colon comment here
Run Code Online (Sandbox Code Playgroud)

你是:

  • 运行命令 :
  • 传递参数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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此行为是非标准的。根据POSIX规范,`:是内置的* special *,并且在特殊命令之前的变量赋值应该在命令完成后仍然有效。如果您将bash调用为sh或使用--posix选项,则会观察到OP的预期行为。 (4认同)
  • (请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_14) (2认同)