简体   繁体   English

如何在 Bash 中设置环境变量数组

[英]How to set an array of environment variables in Bash

I am trying to implement a migration script to export some environment variables in bash.我正在尝试实现一个迁移脚本来导出 bash 中的一些环境变量。

It is more difficult to be explained that to implement.实施起来更难解释。

Basically, there is a set of environment variables and a set of their default values.基本上,有一组环境变量和一组它们的默认值。

A small fragment of the (gigantic) migration script is reported below:下面报告了(巨大的)迁移脚本的一小部分:

REQUIRED_ENVIRONMENT_VARIABLES=( "BAR" "FOO" "BAZ" )
ENVIRONMENT_VARIABLES_DAFAULT_VALUES=( "/some/path" "0" "true" )

for i in "${!REQUIRED_ENVIRONMENT_VARIABLES[@]}"; do 
    echo "checking environment variable [$i] ${REQUIRED_ENVIRONMENT_VARIABLES[$i]} which default value is: [${ENVIRONMENT_VARIABLES_DAFAULT_VALUES[$i]}]"
    if [[ -z "${REQUIRED_ENVIRONMENT_VARIABLES[$i]}" ]]; then
      echo "variable ${REQUIRED_ENVIRONMENT_VARIABLES[$i]} exported with value ${ENVIRONMENT_VARIABLES_DAFAULT_VALUES[$i]}"
      echo "export ${REQUIRED_ENVIRONMENT_VARIABLES[$i]}"="${ENVIRONMENT_VARIABLES_DAFAULT_VALUES[$i]}" >> $HOME/.bash_profile
    fi
done

Simply, the for loop iterates for each variable into REQUIRED_ENVIRONMENT_VARIABLES :简单地说,for 循环将每个变量迭代到REQUIRED_ENVIRONMENT_VARIABLES中:

  • if the var exists and has some value, skip it and continue to the next iteration;如果 var 存在并且具有某些值,则跳过它并继续下一次迭代;
  • if the var doesn't exist, create a new entry export VAR_NAME=DEFAULT_VALUE into the .bash_profile如果 var 不存在,创建一个新条目export VAR_NAME=DEFAULT_VALUE.bash_profile

So, for example, if the original contents of .bash_profile is:因此,例如,如果.bash_profile的原始内容是:

( .bash_profile ) ( .bash_profile )

export FOO=1
export ASD=https://cool.url/
...

after running the migration script, the result should be:运行迁移脚本后,结果应该是:

( .bash_profile ) ( .bash_profile )

export FOO=1
export ASD=https://cool.url/
...
export BAR=/some/path
export BAZ=true

FOO remains untouched because already exists. FOO保持不变,因为已经存在。

The problem with this code is that I see no new entries when I try to append it to the .bash_profile using the echo command.此代码的问题是,当我尝试使用echo命令将其 append 到.bash_profile时,我看不到任何新条目。 Why?为什么?

The problem is in the test问题在测试中

if [[ -z "${REQUIRED_ENVIRONMENT_VARIABLES[$i]}" ]]; then

This expands out an element of the array, and then checks to see if that array element was the null string (not whether it's the name of a variable).这扩展了数组的一个元素,然后检查该数组元素是否是 null 字符串(而不是它是否是变量的名称)。 That is, on the first iteration when i=0 , it expands to:也就是说,在i=0的第一次迭代中,它扩展为:

if [[ -z "BAR" ]]; then

...and since "BAR" is not the null string, the test fails. ...并且由于“BAR”不是 null 字符串,因此测试失败。 What you want is to treat BAR as a variable name, rather than a literal string.您想要的是将BAR视为变量名,而不是文字字符串。 There are a couple of ways to do this.有几种方法可以做到这一点。 One is to use a negated -v test ("is there a variable by this name") (note that this is only available in newer versions of bash):一种是使用否定的-v测试(“是否有此名称的变量”)(请注意,这仅在较新版本的 bash 中可用):

if [[ ! -v "${REQUIRED_ENVIRONMENT_VARIABLES[$i]}" ]]; then

Another option is to use bash's "indirect" variable expansion feature, by adding a !另一种选择是使用 bash 的“间接”变量扩展功能,方法是添加! at the beginning of the expansion:在扩展开始时:

if [[ -z "${!REQUIRED_ENVIRONMENT_VARIABLES[$i]}" ]]; then

Note that these aren't quite the same test;请注意,这些测试并不完全相同。 the first will treat a variable that's set to the null string as set, the second will not.第一个会将设置为 null 字符串的变量视为已设置,第二个不会。

BTW, this is a near-duplicate of "How to check if a variable is set in Bash?"顺便说一句,这几乎是“如何检查 Bash 中是否设置了变量?”的重复。 , but since in this case the variable name is coming from an array, I considered it different enough to treat it as a separate question. ,但由于在这种情况下变量名来自一个数组,我认为它的不同足以将其视为一个单独的问题。

Wouldn't it be easier to code it like this instead of using an array:像这样编码而不是使用数组会不会更容易:

: ${BAR:=/some/path}
: ${FOO:=0}
: ${BAZ:=true}
: ${POOF:=$((FOO+25))}  # Default for variable depends on other variable
export FOO BAR BAZ POOF

In this source, the variables would be untouched if they are already set, but get a value if they are not.在此源中,如果变量已设置,则它们将保持不变,但如果未设置,则获取一个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM