我有一个通过NPM安装的命令(db-migrate
(。我想从命令行中运行它,作为自动化数据库迁移的一部分。脚本的配置文件可以参考环境变量。我已经将数据库凭据设置为另一个文件中的环境变量。因此,我没有将它们设置两次,而是告诉迁移配置使用环境变量。问题是,在运行迁移脚本之前,如何从文件中获取环境变量?另外,如何直接从NPM bin
?
我找到了一个很好的解决方案,因此我要发布问题和答案,至少是我未来自我的好处。
这可以使用一些工具完成:
- 从文件中读取环境变量,并在运行脚本之前将它们设置。要查看,在运行命令之前,设置一个环境变量很容易:
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
更新:
此方法有一些警告。首先是它将使用环境变量污染您当前的外壳。换句话说,运行export...xargs
位后,您可以运行诸如echo $DB_PASS
之类的内容,并且您的密码将显示。为了防止这种情况,请将命令包裹在Parens中:
(export $(cat app.env | xargs) && PATH=$(npm bin):$PATH db-migrate up)
Parens导致该命令在子壳环境中执行。环境变量不会冒出当前的外壳。
第二个警告是,只有在您的环境变量中没有空格时才起作用。如果您想要空间,我根据此要旨评论找到了一个确定的解决方案。创建一个名为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)