本文翻译自:Set environment variables from file of key/value pairs
TL;DR: How do I export a set of key/value pairs from a text file into the shell environment? TL; DR:如何将一组键/值对从文本文件导出到Shell环境中?
For the record, below is the original version of the question, with examples. 作为记录,下面是问题的原始版本,并带有示例。
I'm writing a script in bash which parses files with 3 variables in a certain folder, this is one of them: 我正在bash中编写一个脚本,该脚本分析某个文件夹中具有3个变量的文件,这是其中之一:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
This file is stored in ./conf/prac1 该文件存储在./conf/prac1中
My script minientrega.sh then parses the file using this code: 然后,我的脚本minientrega.sh使用以下代码解析文件:
cat ./conf/$1 | while read line; do
export $line
done
But when I execute minientrega.sh prac1
in the command line it doesn't set the environment variables 但是,当我在命令行中执行minientrega.sh prac1
,它没有设置环境变量
I also tried using source ./conf/$1
but the same problem still applies 我也尝试使用source ./conf/$1
但同样的问题仍然适用
Maybe there is some other way to do this, I just need to use the environment variables of the file I pass as the argument of my script. 也许还有其他方法可以做到,我只需要使用传递的文件的环境变量作为脚本的参数即可。
#1楼
参考:https://stackoom.com/question/1J70L/从键-值对文件中设置环境变量
#2楼
Problem with your approach is the export
in the while
loop is happening in a sub shell, and those variable will not be available in current shell (parent shell of while loop). 您的方法存在的问题是, while
循环中的export
发生在子外壳程序中,并且这些变量在当前外壳程序(while循环的父外壳程序)中不可用。
Add export
command in the file itself: 在文件本身中添加export
命令:
export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"
Then you need to source in the file in current shell using: 然后,您需要使用以下命令在当前shell中获取文件的来源:
. ./conf/prac1
OR 要么
source ./conf/prac1
#3楼
This might be helpful: 这可能会有所帮助:
export $(cat .env | xargs) && rails c
Reason why I use this is if I want to test .env
stuff in my rails console. 我使用它的原因是如果我想在我的rails控制台中测试.env
东西。
gabrielf came up with a good way to keep the variables local. gabrielf提出了一种使变量保持局部的好方法。 This solves the potential problem when going from project to project. 这解决了从一个项目到另一个项目时的潜在问题。
env $(cat .env | xargs) rails
I've tested this with bash 3.2.51(1)-release
我已经使用bash 3.2.51(1)-release
测试了它
Update: 更新:
To ignore lines that start with #
, use this (thanks to Pete's comment ): 要忽略以#
开头的行,请使用以下命令(感谢Pete的注释 ):
export $(grep -v '^#' .env | xargs)
And if you want to unset
all of the variables defined in the file, use this: 如果要unset
文件中定义的所有变量,请使用以下命令:
unset $(grep -v '^#' .env | sed -E 's/(.*)=.*/\1/' | xargs)
Update: 更新:
To also handle values with spaces, use: 要同时使用空格处理值,请使用:
export $(grep -v '^#' .env | xargs -d '\n')
on GNU systems -- or: 在GNU系统上-或:
export $(grep -v '^#' .env | xargs -0)
on BSD systems. 在BSD系统上。
#4楼
You can use your original script to set the variables, but you need to call it the following way (with stand-alone dot): 您可以使用原始脚本来设置变量,但是您需要通过以下方式(带有独立的点)来调用它:
. ./minientrega.sh
Also there might be an issue with cat | while read
cat | while read
也可能有问题cat | while read
cat | while read
approach. cat | while read
方法。 I would recommend to use the approach while read line; do .... done < $FILE
我建议while read line; do .... done < $FILE
使用该方法while read line; do .... done < $FILE
while read line; do .... done < $FILE
. while read line; do .... done < $FILE
。
Here is a working example: 这是一个工作示例:
> 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
#5楼
I have issues with the earlier suggested solutions: 我对较早提出的解决方案有疑问:
- @anubhava's solution makes writing bash friendly configuration files very annoying very fast, and also - you may not want to always export your configuration. @anubhava的解决方案使编写bash友好的配置文件变得非常烦人,而且-您可能不希望始终导出配置。
- @Silas Paul solution breaks when you have variables that have spaces or other characters that work well in quoted values, but
$()
makes a mess out of. 当您使用带空格或其他字符的变量在加引号的值时效果很好时,@ Silas Paul解决方案就会中断,但是$()
会使情况变得一团糟。
Here is my solution, which is still pretty terrible IMO - and doesn't solve the "export only to one child" problem addressed by Silas (though you can probably run it in a sub-shell to limit the scope): 这是我的解决方案,它仍然是非常糟糕的IMO-并不能解决Silas解决的“仅导出到一个孩子”问题(尽管您可以在子shell中运行它来限制范围):
source .conf-file
export $(cut -d= -f1 < .conf-file)
#6楼
eval $(cat .env | sed 's/^/export /')