为啥在同一行上分配变量后shell内置冒号命令“:”会导致分配空字符串值?
Posted
技术标签:
【中文标题】为啥在同一行上分配变量后shell内置冒号命令“:”会导致分配空字符串值?【英文标题】:Why does shell builtin colon command ":" after variable assignment on same line cause empty string value to be assigned?为什么在同一行上分配变量后shell内置冒号命令“:”会导致分配空字符串值? 【发布时间】:2019-12-13 22:04:34 【问题描述】:如果我在赋值后添加 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
【问题讨论】:
它实际上不是空的,它没有设置(尝试[[ -v $MyVar1 ]] || echo 'not set'
作为测试)。
【参考方案1】:
:
是一个成功返回的内置命令(true
的简写版本)。
当您在命令的同一行进行变量赋值时,赋值仅在命令执行期间有效(这通常用于运行设置了临时环境变量的命令)。
所以当你运行时:
MyVar1='my var 1' : colon comment here
你是:
运行命令:
传递参数colon
、comment
和here
(这些被命令删除)
临时变量赋值MyVar1='my var 1'
(这对命令没有影响)
the spec 中描述了此行为:
“简单命令”是一系列可选的变量赋值和重定向,以任意顺序,可选地后跟单词和重定向,由控制运算符终止。
...
如果没有命令名结果,变量赋值将影响当前执行环境。否则,变量赋值要为命令的执行环境导出,不影响当前执行环境(特殊内置除外)。
正如 cmets 中指出的(谢谢!):
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
【讨论】:
所以你是说任何之前冒号(:
)命令基本上被忽略?
命令前的任何变量赋值只会影响命令的执行环境(在你的情况下,:
),而不是当前的执行环境(shell)。
注意这种行为是非标准的。根据 POSIX 规范,:
是一个 special 内置的,并且在一个 special 之前的变量赋值应该在命令完成后保持有效。如果您将bash
调用为sh
或使用--posix
选项,则会观察到OP 的预期行为。
@RobBednark 需要临时分配的一个常见示例是使用read
命令。 IFS=, read a b c
将读取一行输入,以逗号分隔,并将前三个字段分配给 a
,b, and
c. The global value of
IFS` 不受影响。
(见pubs.opengroup.org/onlinepubs/9699919799/utilities/…)以上是关于为啥在同一行上分配变量后shell内置冒号命令“:”会导致分配空字符串值?的主要内容,如果未能解决你的问题,请参考以下文章