TL;DR:如何从文本文件中导出一组键/值对到shell环境中?


为了记录在案,以下是问题的原始版本,并附有示例。

我在bash中写了一个脚本,它在某个文件夹中解析带有3个变量的文件,这是其中之一:

MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"

该文件的存放路径为。/conf/prac1

我的脚本minientrega.sh然后使用以下代码解析文件:

cat ./conf/$1 | while read line; do
    export $line
done

但是当我在命令行中执行minientrega.sh prac1时,它不会设置环境变量

我也尝试使用source ./conf/$1,但同样的问题仍然适用

也许还有其他方法可以做到这一点,我只需要使用我传递的文件的环境变量作为脚本的参数。


当前回答

这是我的变种:

  with_env() {
    (set -a && . ./.env && "$@")
  }

与之前方案相比:

它不会泄漏作用域外的变量(来自.env的值不会暴露给调用者) 不clobber设置选项 返回已执行命令的退出代码 使用posix兼容的set -a 用途。而不是源,避免害羞 如果.env加载失败,则不会调用该命令

with_env rails console

其他回答

SAVE=$(set +o | grep allexport) && set -o allexport && ..环境;评估“$SAVE”

这将保存/恢复您的原始选项,无论它们是什么。

使用set -o alleexport的优点是可以在没有正则表达式的情况下正确地跳过注释。

Set +o本身以bash稍后可以执行的格式输出所有当前选项。同样方便的是:set -o本身以人类友好的格式输出所有当前选项。

如果你得到一个错误,因为你的一个变量包含了一个包含空格的值,你可以尝试重置bash的IFS(内部字段分隔符)为\n,让bash解释cat .env结果为env可执行文件的参数列表。

例子:

IFS=$'\n'; env $(cat .env) rails c

参见:

http://tldp.org/LDP/abs/html/internalvariables.html#IFSREF https://unix.stackexchange.com/a/196761

如果env支持-S选项,则可以使用换行符或转义字符,如\n或\t(参见env):

env -S "$(cat .env)" command

.env文件示例:

KEY="value with space\nnewline\ttab\tand
multiple
lines"

测试:

env -S "$(cat .env)" sh -c 'echo "$KEY"'

我找到的最短的方法是:

你的。env文件:

VARIABLE_NAME="A_VALUE"

那就

. ./.env && echo ${VARIABLE_NAME}

好处:因为它是一个简短的一行程序,所以在软件包中非常有用。json文件

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }

修改自@Dan Kowalczyk

我把它放在~/.bashrc中。

set -a
. ./.env >/dev/null 2>&1
set +a

与Oh-my-Zsh的dotenv插件非常好的交叉兼容。(有Oh-my-bash,但它没有dotenv插件。)