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,但同样的问题仍然适用

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


当前回答

试试这样的方法

for line in `cat your_env_file`; do if [[ $line != \#* ]];then export $line; fi;done

其他回答

export $(grep -v '^#' envfilename | xargs -L 1  -d '\r' -d '\r\n')

这在CentOS上就像一个魅力;当你遇到\r被附加到加载变量的问题时。它还负责注释和空白。

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

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

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

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

以下是我的看法。我有以下要求:

忽略注释行 值中允许有空格 允许空行 能够在默认为.env时传递自定义env文件 允许导出以及内联运行命令 如果env文件不存在,退出

source_env() {
  env=${1:-.env}
  [ ! -f "${env}" ] && { echo "Env file ${env} doesn't exist"; return 1; }
  eval $(sed -e '/^\s*$/d' -e '/^\s*#/d' -e 's/=/="/' -e 's/$/"/' -e 's/^/export /' "${env}")
}

将函数保存到.bash_profile或等效文件后的用法:

source_env                # load default .env file
source_env .env.dev       # load custom .env file
(source_env && COMMAND)   # run command without saving vars to environment

受到哈维尔和其他一些评论的启发。

t=$(mktemp) && export -p > "$t" && set -a && . ./.env && set +a && . "$t" && rm "$t" && unset t

它是如何工作的

Create temp file. Write all current environment variables values to the temp file. Enable exporting of all declared variables in the sources script to the environment. Read .env file. All variables will be exported into current environment. Disable exporting of all declared variables in the sources script to the environment. Read the contents of the temp file. Every line would have declare -x VAR="val" that would export each of the variables into environment. Remove temp file. Unset the variable holding temp file name.

特性

保留环境中已设置的变量的值 .env可以有注释 .env可以有空行 .env不像其他答案那样需要特殊的页眉或页脚(set -a和set +a) .env不需要对每个值都导出 一行程序

如果您想让exec作为脚本的最后一个命令,那么您可以使用execlineb解释器。这是脚本的最后一行:

#!/bin/sh
...
exec envfile -I /etc/default/bla envfile /etc/default/bla-bla my_cmd

envfile……是来自execline套件的命令,它们依赖于“链加载”。 顺便说一句,一旦你进入这个兔子洞,你可能会发现你不再需要壳了(…-)使用execlineb解释器而不是shell来启动服务,以最小的开销是非常有用的,即:

#!/bin/execlineb
...
envfile -I /etc/default/bla
envfile /etc/default/bla-bla
my_cmd