从文件设置环境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)
更简单:
- 抓取文件的内容
- 删除任何空白行(只需要分开一些东西)
- 删除任何意见(只是在你添加了一些…)
- 添加
export
到所有的行 -
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
)