注意:这个一般主题似乎在不止一个 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 中(感谢RudiC)——并获得所需的输出,同时- 从
.env
文件中加载变量,同时 - 将变量保留在该进程调用的本地:它们将在 shell 环境和后续进程中保持未设置状态,而不需要
unset
它们
我可以使用什么单行语法来完成此操作?应该用什么代替下面的问号来满足上面的标准?
% ?????????? ./printenv
hello world
goodnight moon
您是否尝试过在子外壳(in
bash
)中运行它们?像这样,
printenv
只为脚本设置局部变量,而父 shell 的环境保持不变。根据您新的扩展要求(无子外壳),尝试使用(不受欢迎的,危险的)方法
eval
:它将变量的定义和命令放在一行中,然后
eval
s 并执行该行。您可以使用“.script”语法将脚本提供给 shell:
. .env && 。./打印环境
您还可以将“..env”添加到 printenv 脚本的开头。然后你将能够执行 printenv 为:
./打印环境
'printenv' 不是好的名称选择,因为它由 shell 使用。