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,但同样的问题仍然适用
也许还有其他方法可以做到这一点,我只需要使用我传递的文件的环境变量作为脚本的参数。
值中的空格
这里有很多很好的答案,但我发现它们都缺乏对值中空白的支持:
DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5
我发现了2个解决方案,这些值支持空行和注释。
一个基于sed和@javier-buzzi的答案:
source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x "&"/g' .env)
和一个读行在循环基于@john1024答案
while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^\s|^$)" .env)
这里的关键是使用声明-x并将line放在双引号中。我不知道为什么,但当你将循环代码重新格式化为多行时,它不会工作-我不是bash程序员,我只是狼吞虎咽地把这些放在一起,它对我来说仍然是魔法:)
posix兼容的解决方案(不依赖于bash)
正如其他人所注意到的,在这里使用for/while循环的问题是,变量在shell及其子shell之间不共享。然而,我们能做的是使用args/stdin/stdout在shell之间传递文本。
在subshell中设置环境变量在我们获取脚本源代码时是没有帮助的
变量不会向上传播,但我们知道可以将文本发送回去。这个文本也可以是代码,我们可以用eval在当前shell中求值。
如果我们生成用于设置所有环境变量的代码,然后对结果进行计算呢?
create_exports_script() {
echo "$1" | while read line; do
echo "export $line"
done
}
file_contents=$(cat "./conf/myconf.env")
eval $(create_exports_script "$file_contents")
bash中的这种函数式元编程非常灵活。您还可以用这种方式生成bash/sh以外的其他语言。
简单:
获取文件的内容
删除任何空行(以防你分开一些东西)
删除任何注释(以防你添加了一些…)
将export添加到所有行
对整个事件进行评估
eval (cat .env美元| sed - e / ^ $ / d - e / ^ # / d - e ' s / ^ /出口/ ')
另一个选择(你不必运行eval(感谢@Jaydeep)):
export $(cat .env | sed -e /^$/d -e /^#/d | xargs)
最后,如果你想让你的生活真的很简单,把这个添加到你的~/.bash_profile:
函数source_envfile() {export $(cat $1 | sed -e /^$/d -e /^#/d | xargs);}
(请务必重新加载bash设置!!~ /来源。bash_profile或. .只要新建一个标签/窗口,问题就解决了),你这样叫它:source_envfile .env