从键/值对文件中设置环境变量

本文探讨如何在bash脚本中从包含键值对的文本文件中设置环境变量。问题在于,使用`while read`循环时,变量在子shell中设置,不会影响父shell。解决方案包括在文件中添加`export`命令,使用`source`命令或者修改脚本以正确设置变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文翻译自: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 /')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值