从文件设置环境variables

我在bash中编写一个脚本,用一个文件夹中的3个variablesparsing文件,这是其中之一:

MINIENTREGA_FECHALIMITE="2011-03-31" MINIENTREGA_FICHEROS="informe.txt programa.c" MINIENTREGA_DESTINO="./destino/entrega-prac1" 

该文件存储在./conf/prac1中

我的脚本minientrega.sh然后使用下面的代码parsing文件:

 cat ./conf/$1 | while read line; do export $line done 

但是当我在命令行中执行minientrega.sh prac1 ,它不会设置环境variables

我也尝试使用source ./conf/$1但同样的问题仍然适用

也许有一些其他的方式来做到这一点,我只需要使用我通过的文件的环境variables作为我的脚本的参数。

你的方法的问题是while循环中的export发生在子shell中,而这些variables在当前shell(while循环的父shell)中将不可用。

在文件本身中添加export命令:

 export MINIENTREGA_FECHALIMITE="2011-03-31" export MINIENTREGA_FICHEROS="informe.txt programa.c" export MINIENTREGA_DESTINO="./destino/entrega-prac1" 

然后,您需要使用以下命令在当前shell中input文件:

 . ./conf/prac1 

要么

 source ./conf/prac1 

这可能有帮助:

 export $(cat .env | xargs) && rails c 

我使用这个的原因是如果我想在我的rails控制台中testing.env东西。

gabrielf想出了一个保持variables本地的好方法。 这解决了从项目到项目的潜在问题。

 env $(cat .env | xargs) rails 

我已经testing了bash 3.2.51(1)-release

-o allexport使所有以下variables定义被导出。 +o allexport禁用此function。

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

这是另一个sed解决scheme,它不运行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构build一个在systemd单元文件中加载这样的文件时特别有用。

 eval $(cat .env | sed 's/^/export /') 

allexport选项在这里还有其他一些答案中提到, set -a是快捷方式。 find.env真的比循环和导出更好,因为它允许注释,空行,甚至命令生成的环境variables。 我的.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) && set -o allexport && . .env; eval "$SAVE"

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

使用set -o allexport具有正确跳过注释而无需正则expression式的优点。

set +o自己输出所有当前选项的格式,bash可以稍后执行。 也很方便:自行set -o ,以人性化的格式输出所有当前的选项。

提高赛拉斯保罗的答案

在子shell中导出variables使得它们在命令的本地。

(export $(cat .env | xargs) && rails c)

 set -a . ./env.txt set +a 

如果env.txt是这样的:

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

我已经提出了user4040650的答案,因为它很简单,它允许在文件中的注释(即以#开头的行),这对我来说是非常可取的,因为解释variables的注释可以被添加。 只是在原始问题的背景下重写。

如果脚本被minientrega.sh prac1 ,如下所示: minientrega.sh prac1 ,则minientrega.sh可以有:

 set -a # export all variables created next source $1 set +a # stop exporting # test that it works echo "Ficheros: $MINIENTREGA_FICHEROS" 

以下是从设置的文档中提取的:

这个内build是如此复杂,它值得自己的部分。 set允许您更改shell选项的值并设置位置参数,或者显示shellvariables的名称和值。

set [–abefhkmnptuvxBCEHPT] [-o option-name] [argument …] set [+ abefhkmnptuvxBCEHPT] [+ o option-name] [argument …]

如果没有提供选项或参数,则按照当前语言环境sorting,设置显示所有shellvariables和函数的名称和值,格式可以重新用作设置或重置当前设置variables的input。 只读variables不能被重置。 在POSIX模式下,只列出shellvariables。

当提供选项时,它们设置或取消设置shell属性。 选项(如果指定)具有以下含义:

-a创build或修改的每个variables或函数都被赋予export属性,并标记为导出到后续命令的环境中。

而且这也是:

使用“+”而不是“ – ”会导致这些选项被closures。 这些选项也可以在调用shell时使用。 当前的选项集可以在$ – 中find。

在其他答案的基础上,这里是一种只导出文件中的一部分行的方法,包括像PREFIX_ONE="a word"类的空格的值:

 set -a . <(grep '^[ ]*PREFIX_' conf-file) set +a 

您可以使用原始脚本来设置variables,但您需要按照以下方式(使用独立点)进行调用:

 . ./minientrega.sh 

也有可能是cat | while read的问题 cat | while read方法。 我会build议while read line; do .... done < $FILE使用这个方法while read line; do .... done < $FILE while read line; do .... done < $FILE

这是一个工作的例子:

 > cat test.conf VARIABLE_TMP1=some_value > cat run_test.sh #/bin/bash while read line; do export "$line"; done < test.conf echo "done" > . ./run_test.sh done > echo $VARIABLE_TMP1 some_value 

我有早期build议的解决scheme的问题:

  • @ anubhava的解决scheme使得编写bash友好的configuration文件非常快,非常恼人,而且 – 你可能不希望总是导出你的configuration。
  • @Silas Paul解决scheme在你的variables中有空格或其他字符在引用值中运行良好的variables时会中断,但是$()弄糟了。

这是我的解决scheme,这仍然是非常可怕的国际海事组织 – 并没有解决西拉斯解决“只出口给一个孩子”的问题(尽pipe你可以运行在一个子shell来限制范围):

 source .conf-file export $(cut -d= -f1 < .conf-file) 

更简单:

  1. 抓取文件的内容
  2. 删除任何空白行(只需要分开一些东西)
  3. 删除任何意见(只是在你添加了一些…)
  4. 添加export到所有的行
  5. eval整个事情

eval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')

另一个选项(你不必运行eval (感谢@Jaydeep)):

 export $(cat .env | sed -e /^$/d -e /^#/d | xargs) 

如果你的错误是因为你的一个variables包含了一个包含空格的值,你可以尝试将bash的IFS (内部字段分隔符)重置为\n ,让bash将cat .env结果解释为env参数列表可执行文件。

例:

 IFS=$'\n'; env $(cat .env) rails c 

也可以看看:

我的.env:

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

调用:

 source .env; echo $USER; echo $PASS 

当我在shell中尝试重用Docker --env-file时遇到了这个线程。 他们的格式不是bash兼容的,但很简单: name=value ,不引用,不replace。 他们也忽略空白行和#评论。

我不能完全兼容posix,但是这里应该用类似bash的shell(在OSX 10.12.5的zsh和Ubuntu 14.04的bash中testing):

 while read -rl; do export "$(sed 's/=.*$//' <<<$l)"="$(sed -E 's/^[^=]+=//' <<<$l)"; done < <(grep -E -v '^\s*(#|$)' your-env-file) 

在以上链接的文档中,它不会处理三个案例:

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • 它不会处理直通语法(一个裸FOO