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

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


当前回答

在这里的几个其他答案中提到了alleexport选项,其中set -a是快捷方式。获取.env确实比遍历行和导出要好,因为它允许注释、空行,甚至命令生成的环境变量。我的.bashrc包含以下内容:

# .env loading in the shell
dotenv () {
  set -a
  [ -f .env ] && . .env
  set +a
}

# Run dotenv on login
dotenv

# Run dotenv on every new directory
cd () {
  builtin cd $@
  dotenv
}

其他回答

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

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

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

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

-o allexport允许导出以下所有变量定义。+o allexport禁用此功能。

set -o allexport
source conf-file
set +o allexport

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,您将看到该命令产生的结果。

下面是另一个sed解决方案,它不运行eval或需要ruby:

source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)

这添加了导出,将注释保留在以注释开头的行中。

.env内容

A=1
#B=2

样本运行

$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2

我发现这在用EnvironmentFile构造这样一个文件加载到systemd单元文件时特别有用。

我的.env:

#!/bin/bash
set -a # export all variables

#comments as usual, this is a bash script
USER=foo
PASS=bar

set +a #stop exporting variables

调用:

source .env; echo $USER; echo $PASS

参考https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once