使用 env 设置包含空格的环境变量

使用 env 设置包含空格的环境变量

我试图用来env为子进程设置环境变量(从另一个源读取,例如文件)。本质上,我正在尝试以下操作:

env VALUE=thisisatest ./somescript.sh

例如,如果somescript.sh是:

echo $VALUE

然后这将按thisisatest预期打印。但我想从文件加载变量。我已经到了这一点:

env $(cat .vars | xargs -d '\n') ./somescript.sh

但,当任何变量包含空格(并且引号不能按预期工作)时,我会遇到麻烦。例如:

env $(echo 'VALUE="this is a test"' | xargs -d '\n') ./somescript.sh

会报错

env: is: No such file or directory

并尝试:

env $(echo 'VALUE="thisisatest"' | xargs -d '\n') ./somescript.sh

会给我意想不到的:

"thisisatest"

我认为这可以正常工作,因为运行env VALUE="thisisatest" ./somescript.sh打印它时不带引号。

从错误中,我了解到由于某种原因 env 不理解引号意味着后面的值应该是一个字符串。但是,我不确定如何以正确解释引号的方式插入这些变量。

任何人都可以提供任何关于我如何实现这一目标的提示吗?

谢谢!

答案1

命令替换中需要使用双引号,否则 shell 将会对命令替换的结果进行字段分割:

$ env "$(echo 'VALUE="this is a test"')" ./somescript.sh
"this is a test"

要从env文件中读取,您必须让 shell 进行字段分割,但IFS仅设置为换行符,这样您的命令就不会因空格而中断:

$ IFS='
'
$ env $(cat .vars) ./somescript.sh

如果你想从文件中读取,最好只使用源(又名) 文件位于somescript.sh

#!/bin/bash

. .vars
: The rest of script go here

答案2

这有效:

env -S "`cat .vars`" command

首先,在您的文件中,您需要引用变量值。

VALUE="This has spaces"

然后使用该-S标志来解析变量(去掉引号)。

env -S "`cat .vars`" command-refers-to-env-vars

当然,您不能$VALUE在命令中引用,因为该命令是由 shell 评估的事先的的行动env。为此,您需要使用以下内容:

( . .vars ; echo $VALUE )

括号打开一个子 shell,这样您就不会用 中的所有定义污染您的 shell .vars。但是,这些变量仅适用于 shell。它们实际上并不在 中env,因此进程无法通过process.ENV.VALUE调用getenv("VALUE")来访问它们env -S

您可以将两者结合起来

( . .vars ; env -S "`cat .vars`" command-refers-to-envs $VALUE )

答案3

实际上,有一种更好的方法可以做到这一点,并且您可以毫无问题地声明多个变量。

env {'VALUE=thisisatest','FOO=this is a test'} printenv

答案4

我认为你把事情过于复杂化了。

$ env FOO='this is a test' printenv | egrep -i foo
FOO=this is a test

顺便说一句,引号不是问题。如果您想要在值中进行变量替换,请使用双引号;如果你想防止变量替换等,请使用单引号。

哎呀,如果适合您的需要,请使用命令替换。使用格式化字符串。两者都用。

$ env FOO=$'this\tis a test' printenv | egrep -i foo | cat -t
FOO=this^Iis a test
$ env FOO="$(echo $'this\tis a test')" printenv | egrep -i foo | cat -t
FOO=this^Iis a test

哎呀,这可能是使用命令替换的更好示例。这个想法是将一些的输出所需命令到变量中,而不仅仅是在不需要的地方无缘无故地使用命令替换。

$ env FOO="$(man man)" printenv | egrep -iA5 foo=
FOO=man(1)                                    man(1)



NAME
   man - format and display the on-line manual pages

相关内容