【问题标题】:Why doesn't "var=value somecommand" persist the new value for var? [duplicate]为什么“var=value somecommand”不保留 var 的新值? [复制]
【发布时间】:2019-02-19 20:03:08
【问题描述】:
$ A=123
$ echo $A  # now value of A is 123
123

$ A=456 echo a random following command
a random following command
$ echo $A  # we can see that A reminds 123 unchanged
123

为什么它在执行和不执行命令时会有所不同?
任何 office bash 文档链接都有帮助。

【问题讨论】:

  • 顺便说一句,这是 POSIX.2 指定的所有行为(因此对所有符合标准的 shell 来说都是通用的),而不是特定于 bash。

标签: bash shell


【解决方案1】:

这个命令:

A=456 echo a random following command

类似于这个命令:

env A=456 echo a random following command

A 的新值 456 将仅用于 echo 命令。命令echo执行后,变量A恢复原值。

官方文档为Bash Reference Manual: Environment;正如它解释的那样:

任何简单命令或函数的环境都可以通过在其前面加上参数分配来临时扩充,如外壳参数中所述。这些赋值语句只影响该命令看到的环境。


更新 0x00

当我们运行以下命令时:

A=123
A=456 echo $A

输出仍然是123,而不是456。原因是 Bash 在执行命令 A=456 echo $A 之前会先评估 $A。所以命令:

A=456 echo $A

变成

A=456 echo 123

然后我们得到了输出123

但下面的例子不同

A=123
A=456 eval echo '$A'

这个输出是456

因为'$A' 是一个纯字符串,Bash 在运行命令之前不会评估它。当eval 命令运行时,变量A 被Bash 设置为456


更新 0x01

子shell也是一个子进程,但是没有标记为导出的变量仍然可用于子shell。

Bash Reference Manual: Command Execution Environment,正如它解释的那样:

命令替换、用括号分组的命令和异步命令在作为 shell 环境副本的子 shell 环境中调用

A=123
( eval echo \$A )

输出为123。即使我们把(eval echo \$A)放到后台,输出仍然是123

A=123
( eval echo \$A )&

当我们执行一个简单的命令,而不是一个内置或shell函数,比如执行一个脚本。此脚本在单独的 shell 环境中调用。只有标记为导出的 shell 变量可用于分离的环境。

A=123
bash -c 'echo A1=$A'
export A
bash -c 'echo A2=$A'

输出是:

A1=
A2=123

【讨论】:

  • 谢谢,这回答了我的一半问题。我读过一些文字here,它解释了A=123(与export A=123)部分:A=123定义了一个shell变量,而export使它成为一个环境变量(然后可以影响孩子进程)。
  • 请注意关于How to Answer 中“...之前已经被多次询问和回答”的问题的要点。
  • @CharlesDuffy 你的编辑(尤其是标题,LOL)绝对不是我的初衷。我会尽快更新我的问题。我一开始就知道为什么"A=132 echo $A" different from "A=132; echo $A"
  • 那么请写一个确实概括问题的标题,而不仅仅是描述它与什么一般主题相关。
  • ...如果问题是“为什么“var=value somecommand”不保留 var 的新值?”,例如,这是一个合理的问题(但 知识库中已有答案)。
猜你喜欢
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
相关资源
最近更新 更多