运行以下代码:
a=one; echo $a
a=two echo $a
a=three echo $a >$a
结果
一个
一个
和一个名为&#34的创建文件;一个"内容"一个"
为什么变量在第2行没有变为two
而在第3行变为three
?
答案 0 :(得分:6)
当一个赋值用作命令本身而不是作为其他命令的前缀(例如echo
)时,它会做一些不同的事情。当它本身用作命令时,它将shell变量设置为该值。当用作其他命令的前缀时,它在命令的环境中设置该变量,但不在shell 中设置。
因此,请看第一个示例a=one; echo $a
,其中分号在同一行上生成这两个命令。第一个命令将shell变量a
设置为值"一个",然后对于第二个命令,shell将a
扩展为"一个",然后将其作为参数传递给echo
。
在第二个示例a=two echo $a
中,分配是echo
命令的前缀,因此echo
将执行,a
设置为"两个& #34;在它的环境中。但$a
由shell扩展,而不是由echo
命令扩展,a
仍然设置为"一个"作为shell变量,以便使用该值。
第三个例子a=three echo $a >$a
与第二个例子非常相似。 shell将$a
扩展为"一个" (因为它是shell变量的值),然后执行echo one
,a
设置为"三"在其环境和输出中定向到名为" one"。
export
shell变量。默认情况下,shell变量不会在shell执行的命令环境中设置。也就是说,它们是shell变量,而不是环境变量。但是如果你export
一个shell变量,它就会变成一个环境变量,并且会被该shell运行的后续命令继承。所以......
这设置了一个shell变量,该变量不会传递给命令'环境:
a=one
这为此命令设置的环境变量,而不是shell或更高版本的命令:
b=two somecommand
这在shell中设置了一个环境变量,因此shell 和可以从该shell运行所有后续命令:
export c=three
这也是一样的事情:
d=four
export d
您可以在分配给它们之前,之后或分配时将shell变量导出到环境中。
答案 1 :(得分:2)
在您的脚本上运行Shellcheck:
In x.sh line 2:
a=two echo $a
^-- SC2097: This assignment is only seen by the forked process.
^-- SC2098: This expansion will not see the mentioned assignment.
In x.sh line 3:
a=three echo $a >$a
^-- SC2097: This assignment is only seen by the forked process.
^-- SC2098: This expansion will not see the mentioned assignment.
^-- SC2094: Make sure not to read and write the same file in the same pipeline.
^-- SC2094: Make sure not to read and write the same file in the same pipeline.
然后根据需要查找SC ....代码,例如SC2097。
在这种情况下,您的命令是var=... someCommand with params
,因此该变量仅针对该命令设置,即在该过程中。
这也是分号(a=one; echo $a
)的第一行不同的原因。 man bash
声明:
由a分隔的命令;按顺序执行
因此,您设置变量,然后将echo
作为两个单独的操作运行。