![何时在环境变量和命令之间使用分号](https://linux22.com/image/22413/%E4%BD%95%E6%97%B6%E5%9C%A8%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E5%92%8C%E5%91%BD%E4%BB%A4%E4%B9%8B%E9%97%B4%E4%BD%BF%E7%94%A8%E5%88%86%E5%8F%B7.png)
谁能解释为什么需要分号才能被LANG
bash 视为更新?
不起作用:
> LANG=Ja_JP bash -c "echo $LANG"
en_US
作品:
> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP
我在 linux 上使用 bash 4.1.10,在 cygwin 下使用相同版本
答案1
读取命令时进行参数和其他类型的扩展,前它被执行了。
第一个版本LANG=Ja_JP bash -c "echo $LANG"
是单个命令。在如此解析之后,$LANG
将扩展到en_US
执行任何内容之前。一旦bash
处理完输入,它就会分叉一个进程,LANG=Ja_JP
按预期添加到环境中,然后执行bash -c echo en_US
。
您可以使用单引号(即LANG=Ja_JP bash -c 'echo $LANG'
outputs)来防止扩展Ja_JP
。
请注意,当您将变量赋值作为命令的一部分时,该赋值仅影响该命令的环境,而不影响 shell 的环境。
第二个版本LANG=Ja_JP; bash -c "echo $LANG"
实际上是按顺序执行的两个单独的命令。第一个是没有命令的简单变量赋值,因此它会影响您当前的 shell。
因此,尽管单个;
.
完全偏离主题,但我可能建议附加一个.UTF-8
when 设置LANG
.如今,在 21 世纪,没有充分的理由不使用 Unicode。
答案2
VAR=value; somecommand
相当于
VAR=value
somecommand
这些是相继执行的不相关命令。第一个命令为 shell 变量赋值VAR
。除非VAR
它已经是一个环境变量,否则它不会导出到环境中,而是保留在 shell 内部。声明export VAR
将导出VAR
到环境中。
VAR=value somecommand
是不同的语法。赋值VAR=value
是给环境的,但是这个赋值只是在执行环境中进行的somecommand
,而不是为了shell后续的执行。
举例来说:
# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1 # displays "value"
env | grep '^VAR1=' # displays nothing
VAR2=value env | grep '^VAR2=' # displays "VAR2=value"
echo $VAR2 # displays nothing
答案3
这是我从研究中收集到的信息的摘要:
有两种类型:环境变量和 shell 变量。
在程序及其子程序/进程/子 shell 中,环境变量可用。 shell 变量仅在当前 shell 中可用。
https://askubuntu.com/a/26322/326584
首先如何echo $VAR
运作
每当终端/shell/bash 看到 $ 符号时,它就会执行称为“参数扩展”的操作。这意味着变量被值替换。
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
因此,如果VAR
值为“hello”,则echo $VAR
变为echo 'hello'
。
这意味着这有效......
TEST=123
echo $TEST
// 123
但以下内容不起作用,因为在命令能够设置变量之前变量已被替换。
TEST2=999 echo $TEST2
// nothing...
但如果你添加分号..
TEST2=999; echo $TEST2
它与..相同
TEST2=999
echo $TEST2
..其工作原理与以前相同。
由于 shell 变量不会传递给子进程/子进程,因此当您调用命令时它会创建一个新进程,因此...
TEST3=111
node -e 'console.log(process.env.TEST3)'
或者
TEST3=111
printenv TEST3
两者都没有打印任何内容。 Shell 变量不被 chld 进程继承。使用export创建shell变量,一个环境变量..
export TEST3=111
printenv TEST3
//111
有一个例外...
VAR=123 printenv VAR
VAR=123 VAR2=456 printenv VAR2 //even multiple vars
基本上,如果像这样编写并在调用命令之后立即设置,那么它只会临时为该命令设置环境变量。它甚至没有设置 shell var。将其视为全新的语法。
VAR=123 printenv VAR // 123
echo $VAR // nothing
VAR=123
echo $VAR // 123