我有一个通过 npm 安装的命令 (db-migrate
)。我想从命令行运行它作为自动化数据库迁移的一部分。脚本的配置文件可以引用环境变量。我已经在另一个文件中将数据库凭据设置为环境变量。因此,我没有将它们设置两次,而是告诉迁移配置使用环境变量。问题是,在运行迁移脚本之前如何从文件中获取环境变量?另外,如何直接从 npm bin
运行迁移脚本?
我找到了一个很好的通用解决方案来解决这个问题,所以我发布这个问题和答案,至少是为了我 future 的自己。
最佳答案
这可以使用一些工具来完成:
- 从文件中读取环境变量并在运行脚本之前设置它们。回顾一下,在运行命令之前设置环境变量很简单:
PORT=3000 node index.js
但是我们想从文件中读取变量。这可以使用 export
和 xargs
来完成:
export $(cat app.env | xargs)
- 我们希望直接从 npm 的
bin
运行脚本。可以使用npm bin
获取bin
文件夹的路径。因此,我们只需在运行命令之前将其添加到路径中即可:
PATH=$(npm bin):$PATH
- 现在将它们放在一起:
export $(cat app.env | xargs) && PATH=$(npm bin):$PATH db-migrate up
这会读取环境变量,设置它们,将 npm bin
添加到路径,然后运行迁移脚本。
顺便说一下,app.env
的内容看起来像这样:
PORT=3000
DB_NAME=dev
DB_USER=dev_user
DB_PASS=dev_pass
更新:
此方法有一些注意事项。首先,它会用环境变量污染你当前的 shell。换句话说,在运行 export...xargs
位后,您可以运行 echo $DB_PASS
之类的命令,然后您的密码就会显示出来。为了防止这种情况,请将命令括在括号中:
(export $(cat app.env | xargs) && PATH=$(npm bin):$PATH db-migrate up)
括号导致命令在子 shell 环境中执行。环境变量不会冒泡到您当前的 shell。
第二个警告是,只有当您的环境变量中没有空格时,这才有效。如果你想要空格,我找到了一个基于 this gist comment 的好解决方案。 。创建一个名为 load-env.sh
的文件:
# loads/exports env variables from a file
# taken from: https://gist.github.com/judy2k/7656bfe3b322d669ef75364a46327836#gistcomment-3239799
function loadEnv() {
local envFile=$1
local isComment='^[[:space:]]*#'
local isBlank='^[[:space:]]*$'
while IFS= read -r line; do
[[ $line =~ $isComment ]] && continue
[[ $line =~ $isBlank ]] && continue
key=$(echo "$line" | cut -d '=' -f 1)
value=$(echo "$line" | cut -d '=' -f 2-)
eval "export ${key}=\"$(echo \${value})\""
done < "$envFile"
}
然后像这样运行你的命令:
(source scripts/load-env.sh && loadEnv app.env && PATH=$(npm bin):$PATH db-migrate up)
关于node.js - 如何将环境变量从文件传递到 Node 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56013874/