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

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


当前回答

我的看法是:

我打印文件,删除注释行,空行,并从“=”符号中分离键/值。然后应用导出命令。

这种解决方案的优点是文件可以在值中包含特殊字符,如管道、html标记等,并且值不需要像真正的属性文件那样被引号包围。

# Single line version
cat myenvfile.properties | grep -v '^#' | grep '=' | while read line; do IFS=\= read k v <<< $line; export $k="$v"; done

# Mutliline version:
cat myenvfile.properties | grep -v '^#' | grep '=' | while read line; do 
  IFS=\= read k v <<< $line
  export $k="$v"
done

其他回答

如何保存变量:

printenv | sed 's/\([a-zA-Z0-9_]*\)=\(.*\)/export \1="\2"/' > myvariables.sh

如何装载它们

source myvariables.sh

不知道为什么,或者我错过了什么,但在经历了大部分答案和失败之后。我意识到通过这个。env文件:

MY_VAR="hello there!"
MY_OTHER_VAR=123

我可以简单地这样做:

source .env
echo $MY_VAR

输出:你好!

似乎在Ubuntu linux中工作得很好。

我对之前建议的解决方案有问题:

@anubhava的解决方案使得编写bash友好的配置文件非常烦人,而且-你可能不想总是导出你的配置。 @Silas Paul解决方案中断时,你的变量有空格或其他字符,在引号值中工作得很好,但$()使混乱。

以下是我的解决方案,在我看来仍然很糟糕——并且不能解决Silas提出的“只导出到一个孩子”的问题(尽管你可能可以在子shell中运行它来限制范围):

source .conf-file
export $(cut -d= -f1 < .conf-file)
set -a
. ./env.txt
set +a

如果env.txt像这样:

VAR1=1
VAR2=2
VAR3=3
...

解释 -a等价于alleexport。换句话说,shell中的每个变量赋值都被导出到环境中(供多个子进程使用)。更多信息可以在Set内置文档中找到:

-a每个创建或修改的变量或函数都被赋予export属性,并标记为可导出到后续命令的环境。 使用“+”而不是“-”会关闭这些选项。还可以在调用shell时使用这些选项。当前选项集可以在$-中找到。

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

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

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

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