注意:这个一般性主题似乎在多个 SE 网站上都被令人作呕地涵盖,但请仔细阅读所有详细信息 - 我没有发现任何涵盖下面描述的所有标准的问题。
zsh
另外:我在下面的示例中使用。我希望有一个符合 POSIX 标准的解决方案,但这并不是一个硬性要求:能够工作bash
并且zsh
足够好的东西。
这是一个帮助澄清问题标题的示例:
假设我有以下两个文件:
% ls -AF
.env printenv*
% cat printenv
echo $LOCAL_MESSAGE_1
echo $LOCAL_MESSAGE_2
% cat .env
LOCAL_MESSAGE_1="hello world"
LOCAL_MESSAGE_2="goodnight moon"
我想执行该脚本printenv
并在中看到以下内容stdout
:
hello world
goodnight moon
如果这些变量在我的环境中不存在,脚本将打印空行(如预期):
% unset LOCAL_MESSAGE_1
% unset LOCAL_MESSAGE_2
% ./printenv
如果我在执行脚本之前设置变量,它们将可供脚本使用,但仅限于该单个进程,而不适用于从同一 shell 启动的任何后续进程:
% LOCAL_MESSAGE_1="hello world" LOCAL_MESSAGE_2="goodnight moon" ./printenv
hello world
goodnight moon
% ./printenv
所以,我的问题是:如何根据以下标准复制上一个示例中的行为?
printenv
在当前 shell 中不加修改地运行— 而不是在子 shell 中运行(感谢鲁迪克) — 并获得所需的输出,同时也- 从文件加载变量
.env
,同时还 - 保持该进程调用的本地变量:它们将在 shell 环境和后续进程中保持未设置状态不需要
unset
他们
我可以使用什么单行语法来完成此任务?应该用什么代替下面的问号才能满足上述标准?
% ?????????? ./printenv
hello world
goodnight moon
答案1
您是否尝试过在子外壳(in )中运行它们bash
?喜欢
( . .env; . ./printenv )
hello world
goodnight moon
这样,printenv
仅为脚本设置 LOCAL 变量,而父 shell 的环境保持不变。
根据您的新的扩展要求(无子外壳),请尝试使用 (不受欢迎,危险) 的方法eval
:
eval $(< .env) ./printenv
hello world
goodnight moon
它将变量的定义和命令放在一行中,然后eval
执行该行。
答案2
答案3
您可以使用“.script”语法将脚本来源到 shell:
。 .env && . ./printenv
您还可以将“. .env”添加到 printenv 脚本的开头。然后你将能够执行 printenv :
./printenv
“printenv”不是一个好的名称选择,因为它由 shell 使用。