为什么"var = value somecommand"没有为var保留新值?

mit*_*tnk 2 bash shell

$ 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
Run Code Online (Sandbox Code Playgroud)

为什么在使用和不使用命令时它的工作方式不同?
任何办公室bash doc链接都很有帮助.

Fen*_*eng 8

这个命令:

A=456 echo a random following command
Run Code Online (Sandbox Code Playgroud)

类似于这个命令:

env A=456 echo a random following command
Run Code Online (Sandbox Code Playgroud)

新价值456A将只用于echo命令.执行命令后echo,变量A重新获得原始值.

官方文件是Bash参考手册:环境 ; 正如它解释:

任何简单命令或函数的环境都可以通过在参数赋值前添加前缀来临时扩充,如Shell参数中所述.这些赋值语句仅影响该命令所见的环境.


更新0x00

当我们运行以下命令时:

A=123
A=456 echo $A
Run Code Online (Sandbox Code Playgroud)

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

A=456 echo $A
Run Code Online (Sandbox Code Playgroud)

A=456 echo 123
Run Code Online (Sandbox Code Playgroud)

然后我们得到了输出123.

但是下面的例子是不同的

A=123
A=456 eval echo '$A'
Run Code Online (Sandbox Code Playgroud)

这个输出是456.

因为'$A'是一个普通字符串,Bash不会在运行命令之前对其进行评估.当eval命令运行时,变量由Bash A设置为456.


更新0x01

子shell也是子进程,但是未标记为导出的变量仍可用于子shell.

Bash参考手册:命令执行环境,如下所述:

命令替换,用括号分组的命令和异步命令在子shell环境中调用,该环境是shell环境的副本

A=123
( eval echo \$A )
Run Code Online (Sandbox Code Playgroud)

输出是123.即使我们投入(eval echo \$A)后台,输出仍然是123.

A=123
( eval echo \$A )&
Run Code Online (Sandbox Code Playgroud)

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

A=123
bash -c 'echo A1=$A'
export A
bash -c 'echo A2=$A'
Run Code Online (Sandbox Code Playgroud)

输出是:

A1=
A2=123
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这回答了我的一半问题.我已经阅读了一些文本[这里](https://ss64.com/bash/export.html),它解释了裸露的`A = 123`(vs`export A = 123`)部分:`A = 123`定义一个shell变量,而`export`使它成为一个环境变量(然后可以在子进程中受到影响). (2认同)