首页 > 解决方案 > 在评估文件以设置单个命令的环境变量时,如何支持注释?

问题描述

我正在处理一个带有文件的项目,并按如下方式variables.env添加和评论它:VAR_THREE

VAR_ONE=val1
VAR_TWO=val2

# comment the purpose of the new variable
VAR_THREE=val3

从命令行我运行它来设置变量并启动程序(通过项目中现有的 shell 脚本运行):

eval $(cat variables.env) java -jar my.jar

该评论似乎适用于之后的所有内容,包括java命令,通过检查很明显echo $VAR_THREE没有值,并且我的 .jar 没有任何输出。如果我离开我的评论variables.env VAR_THREE设置并且程序运行并产生输出。

有没有办法允许变量文件中的注释而不适用于后续行和命令?

标签: bashshell

解决方案


简单的事情是使用子shell。

(set -a; . variables.env; exec java -jar my.jar)

要将其分解为其组成部分:

  • ( ... )将整个代码放在一个子shell中——一个使用fork()但没有exec-family调用创建的shell的副本——所以没有一个变量会在完成后持续存在。
  • set -a告诉 shell 自动将任何变量导出到环境中(因此它们对子进程可见java)。由于子shell,这仍然仅限于此处运行的代码。
  • . variables.env是更便携的等价物source variables.env,将 的内容variables.env作为脚本运行。
  • exec告诉已经存在的子shell用可执行文件替换自己。java如果没有exec(并且缺少一些特定于场景/未记录的运行时优化),运行外部命令会创建一个新的子shell,告诉的子shell 用java可执行文件替换自己,然后等待新的子shell 退出;通过运行exec java,我们消耗了我们已经制作的子shell,而不是创建第二个。

...并且作为一个额外的好处,您不会得到不希望的副作用eval(在传递包含空格或其他语法敏感字符的参数时导致额外的字符串拆分、全局扩展和其他潜在的混淆)。


推荐阅读