【问题标题】:Bash export variables but only for current commandBash 导出变量,但仅适用于当前命令
【发布时间】:2020-09-25 03:14:36
【问题描述】:

我想在运行节点脚本之前从文件中加载一些环境变量,以便脚本可以访问它们。但是,我不希望在脚本执行完成后在我的 shell 中设置环境变量。

我可以像这样加载环境变量:

export $(cat app-env-vars.txt | xargs) && node my-script.js

但是,在命令运行之后,所有的环境变量现在都在我的 shell 中设置了。

我问这个问题来回答它,因为我想出了一个解决方案,但在 SO 上找不到答案。

【问题讨论】:

  • 改用dotenv 运行您的脚本。
  • 类似node -r dotenv/config my-script.js dotenv_config_path=app.env,我相信。
  • @chepner 好建议。我知道dotenv。在这种情况下,我有充分的理由不使用它。另外,我想要一个通用的解决方案,可以在这个特定示例之外使用。
  • 请记住,解析.env 文件的规则不与shell 的解析规则相同。来自github.com/motdotla/dotenv 的示例:必须编写像FOO= some value 这样的行FOO=" some value" 才能让shell 正确处理它。 shell 也不会将\n 扩展为换行符。
  • @chepner 有价值的说明。谢谢。我并没有真正尝试专门针对.env 格式;只是意味着它是一个包含 shell 样式环境变量的文件。我相应地重命名了示例中的文件。

标签: node.js linux bash shell zsh


【解决方案1】:

如果您将命令用括号括起来,exports 将被限定在这些括号内,并且不会污染全局 shell 命名空间:

(export $(cat app-env-vars.txt | xargs) && node my-script.js)

执行命令后从app.env 文件中回显其中一个环境变量会将其显示为空。

【讨论】:

  • 这不适用于所有有效的 .env 文件,因为未引用命令替换的 shell 扩展以及 shell 分配与 github.com/motdotla/dotenv 中记录的规则之间的语法差异。
  • @chepner 我并没有真正尝试专门针对.env 格式;只是意味着它是一个包含 shell 样式环境变量的文件。我相应地重命名了示例中的文件。
  • 对于像FOO="x y z" 这样的非常合理的任务仍然不起作用。结果将是FOO=x 和导出但未定义的变量y 和z。
  • @chepner 注意。谢谢。这解决了执行后不污染我的 shell 命名空间的直接问题。
【解决方案2】:

这就是env 命令的用途:

env - 在修改后的环境中运行程序

你可以试试这样的:

env $(cat app-en-vars.txt) node my-script.js

这(以及任何未引用的$(...) 扩展)受word splitting 和glob expansion 的约束,这两者都很容易导致环境变量等问题。

更安全的方法是使用数组,如下所示:

my_vars=(
  FOO=bar
  "BAZ=hello world"
  ...
)
env "${my_vars[@]}" node my-script.js

如果需要,您可以populate an array from a file。请注意,您还可以将-i 与env 一起使用仅传递您明确设置的环境变量。


如果您信任 .txt 的文件内容,并且它包含有效的 Bash 语法,您应该 source 它(并且可能将其重命名为 .sh/.bash 扩展名)。然后,您可以使用子shell,正如您在答案中发布的那样,防止sourced 状态泄漏到父shell:

( source app-env-vars.txt && node my-script.js )

【讨论】:

  • 真的很高兴了解 env 命令。尽管此解决方案不处理引用值(例如 VARNAME="a b c")。 Diego 发布的 eval 解决方案似乎很理想。
  • 如果 .txt 文件实际上是一个有效的 Bash 文件(并且您信任它),您应该 source 它。我已经更新了我的答案。
【解决方案3】:

如果你的文件只包含变量

FOO='x y z'
BAR='bar'
...

你可以试试

eval $(< app-en-vars.txt) node my-script.js

【讨论】:

  • 不错!这是一个很好的解决方案。它适用于引用的值。我喜欢它。
  • 这不适用于各种可能的情况,例如 .txt 文件中的 Bash 语法。使用eval 允许任意shell injection exploits。即使您信任 .txt 文件的内容,任何不正确引用的内容都可能引发意外行为。
  • @dimo414 这就是为什么我开始指定条件的原因
猜你喜欢
  • 2016-05-10
  • 2016-07-17
  • 1970-01-01
  • 2016-09-07
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
相关资源
最近更新 更多