首页 > 解决方案 > 为什么在同一行上分配变量后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.

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

标签: bashshellshvariable-assignmentbuilt-in

解决方案


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

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

所以当你运行时:

MyVar1='my var 1'  : colon comment here

你是:

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

规范中描述了这种行为:

“简单命令”是一系列可选的变量分配和重定向,以任何顺序,可选地后跟单词和重定向,由控制运算符终止。

...

如果没有产生命令名,变量赋值将影响当前的执行环境。否则,变量赋值将被导出用于命令的执行环境,并且不会影响当前的执行环境(除了特殊的内置)。

正如评论中指出的(谢谢!),: 特殊的 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

推荐阅读