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,但同样的问题仍然适用
也许还有其他方法可以做到这一点,我只需要使用我传递的文件的环境变量作为脚本的参数。
source的问题在于它要求文件具有正确的bash语法,而一些特殊字符会破坏它:=、"、'、<、>等。所以在某些情况下你可以
source development.env
它会起作用的。
然而,这个版本可以承受值中的所有特殊字符:
set -a
source <(cat development.env | \
sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
set +a
解释:
-a意味着每个bash变量都将成为环境变量
/^#/d删除注释(以#开头的字符串)
/^\s*$/d删除空字符串,包括空格
"s/'/'\\\ " /g"将每个单引号替换为'\ ",这是bash中的一个生成引号的技巧序列:)
"s/=\(.*\)/='\1'/g"将每个a=b转换为a='b'
因此,你可以使用特殊字符:)
要调试这段代码,将source替换为cat,您将看到该命令产生的结果。
以下是我的看法。我有以下要求:
忽略注释行
值中允许有空格
允许空行
能够在默认为.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
受到哈维尔和其他一些评论的启发。