Ear*_*ine 25 command-line bash environment-variables
这个命令:
A=10 echo $A
Run Code Online (Sandbox Code Playgroud)
打印一个空行。为什么不10呢?为什么就地临时环境设置不起作用?
我想知道原因和解释而不是解决方案。
我用了
LANG=C gcc ...
Run Code Online (Sandbox Code Playgroud)
强制 gcc 使用回退语言(英语)而不是系统语言(中文)。所以我假设VAR=value前缀将为它后面的命令设置一个临时环境。不过我好像有点误会了。
Mes*_*ion 37
当您使用LANG=C gcc ... 时,shell仅为gcc的环境设置 LANG ,而不是为当前环境本身设置 LANG (请参阅注释)。因此,完成后,将恢复到其先前的值(或未设置)。gccLANG
此外,当您使用A=10 echo $A它时,替换 $A 的是shell,而不是 echo,并且这种替换(称为“扩展”)发生在评估语句(包括赋值)之前,因此要按预期工作,A必须已经设置了在该声明之前的当前环境中。
这就是为什么A=10 echo $A不能按预期工作的原因:A=10将为 echo 设置,但 echo 在内部忽略环境变量的值A。And$A替换为当前 shell 中设置的值(无),然后作为参数传递给 echo。
所以你的假设是正确的:VAR=value command 确实有效,但这仅在command内部使用VAR时才相关。如果没有,您仍然可以将其value作为参数传递给command,但参数会被当前的shell替换,因此必须在使用之前设置它们:VAR=value; command "$VAR"
如果你知道如何创建一个可执行脚本,你可以试试这个作为测试:
#!/bin/sh
echo "1st argument is $1"
echo "A is $A"
Run Code Online (Sandbox Code Playgroud)
将其另存为testscript并尝试:
$ A=5; A=10 testscript "$A"; echo "$A"
1st argument is 5
A is 10
5
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是,有必要了解shell和环境变量以及程序参数之间的区别。
这里有一些很好的参考:
.
(*) 注意:从技术上讲,shell也会在当前环境中设置,原因如下:某些命令,例如echo,read和test是shell 内置命令,因此它们不会产生子进程。它们在当前环境中运行。但是 shell 负责分配只持续到命令运行,所以对于所有实际目的来说效果是一样的:分配只能由单个命令看到。
Gil*_*il' 22
这是评估命令的不同步骤发生的顺序的问题。
A=10 echo $A首先将命令解析为由三个单词组成的简单命令A=10,echo和$A。然后每个单词都经过变量替换,$A即将变量扩展如转换为它们的值(我省略了不做任何可见的步骤)。
如果最初A具有值foo,则扩展步骤的结果是一个简单的命令,它仍然包含三个字:A=10,echo和foo。(此时,shell 还会记住哪些字符最初在引号内——在本例中,没有。)下一步是执行命令。由于A=10以有效的变量名开头,后跟等号,因此被视为赋值;在命令执行期间,该变量在 shell 和环境中都A设置为10。(通常您需要在环境中写入export AhaveA而不仅仅是作为 shell 变量;这是一个例外。)下一个单词不是赋值,因此它被视为命令名称(它是一个内置命令)。这echocommand 不依赖于任何变量,因此A=10 echo $A与echo $A.
如果只想在命令的持续时间内设置变量,但在执行命令时考虑赋值,则可以使用子shell。由括号指示的子shell 使所有状态更改(变量分配、当前目录、函数定义等)成为子shell 本地的。
(A=10; echo $A)
Run Code Online (Sandbox Code Playgroud)
作出这样的export A=10,如果你想将变量导出到环境,以便它是由外部程序可见。