使用 env 在 bash 中为一个程序调用设置环境变量

Posted

技术标签:

【中文标题】使用 env 在 bash 中为一个程序调用设置环境变量【英文标题】:Setting environment variable for one program call in bash using env 【发布时间】:2012-12-09 12:03:10 【问题描述】:

我正在尝试通过命令 env 调用带有修改环境的 shell 命令。

根据说明书

env HELLO='Hello World' echo $HELLO

应该回显Hello World,但它没有。 如果我这样做了

HELLO='Hello World' bash -c 'echo $HELLO'

它按预期打印Hello World(感谢this answer 提供此信息)。

我在这里错过了什么?

干杯, 尼克拉斯

【问题讨论】:

完全没有扩展的健全性检查是HELLO='Hello World' env | grep HELLO,它可以满足要求,但在实践中远不如接受的答案有用。 【参考方案1】:

这是因为在您的第一种情况下,您当前的 shell 在运行命令之前扩展了 $HELLO 变量。而且您当前的 shell 中没有设置 HELLO 变量。

env HELLO='Hello World' echo $HELLO

会这样做:

展开任何给定的变量,在本例中为$HELLO 使用 3 个参数 'HELLO=Hello World''echo'''(一个空字符串,因为当前 shell 中没有设置 HELLO 变量)运行 env env 命令将运行并在其环境中设置HELLO='Hello World' env 将运行 echo 并带有参数 ''(一个空字符串)

如您所见,当前 shell 扩展了未设置的 $HELLO 变量。

HELLO='Hello World' bash -c 'echo $HELLO'

会这样做:

为以下命令设置变量HELLO='Hello World 使用'-c''echo $HELLO' 两个参数运行bash 由于最后一个参数是用单引号括起来的,所以里面没有任何东西被展开 新的 bash 将依次运行命令 echo $HELLO 要在新的 bash 子 shell 中运行 echo $HELLO,bash 首先扩展它可以扩展的任何内容,在这种情况下为 $HELLO,然后父 shell 为我们将其设置为 Hello World。 子shell运行echo 'Hello World'

如果您尝试这样做,例如这个:

env HELLO='Hello World' echo '$HELLO'
当前的 shell 会扩展它可以扩展的任何东西,这没什么,因为 $HELLO 用单引号括起来 使用'HELLO=Hello World''echo''$HELLO'三个参数运行env env 命令将运行并在其环境中设置HELLO='Hello World' env 将使用参数'$HELLO' 运行 echo

在这种情况下,没有可以扩展$HELLO 的shell,所以echo 接收字符串$HELLO 并打印出来。变量扩展仅由 shell 完成。

【讨论】:

【参考方案2】:

我认为发生的事情类似于this situation,我也对此感到困惑。

简而言之,第一种情况下的变量扩展是由当前环境中没有$HELLO 的shell 完成的。不过,在第二种情况下,单引号会阻止当前 shell 进行变量扩展,因此一切都按预期工作。

注意将单引号更改为双引号如何阻止此命令按您想要的方式工作:

HELLO='Hello World' bash -c "echo $HELLO"

现在这将失败,原因与您问题中的第一个命令相同。

【讨论】:

正确。在第一种情况下,扩展变量的是当前 shell。在第二种情况下,执行它的是新的bash 也非常感谢您的快速回复!不幸的是,我只能给一个答案打一个漂亮的绿色勾【参考方案3】:

这很有效,对我有好处

$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!

【讨论】:

我不认为这适用于问题的“一个程序调用”部分。此处的 vars 将为当前会话保持设置,因此您将能够继续回显它们。【参考方案4】:

这是确认 shell 是否按预期工作的更简单方法。

env A=42 env
env

第一个命令将A 设置为42 并运行env。第二个命令也运行env。比较两者的输出。

【讨论】:

【参考方案5】:

如前所述,传递给echo 的变量的扩展发生在该变量设置之前。

之前的答案中尚未提到的一种替代方法是使用:

$ a=abc eval 'echo $a'
abc

$ echo $a
<blank>

请注意,您必须使用a=abc cmd 语法而不是env a=abc cmd 语法;显然env 不能很好地与内置的eval 配合使用。

【讨论】:

以上是关于使用 env 在 bash 中为一个程序调用设置环境变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GitHub Actions 中使用 bash 表达式设置 env var?

RBash - 受限的Bash绕过

如何从 powershell 中为 bash 设置环境变量?

在 terraform 文件而不是 env 变量中为 Terraform 提供凭据

在 Docker 中为 AWS Elastic Beanstalk 构建期间访问 .env 变量

如何在 Laravel 5 中为表使用全局前缀