更新

更新

抱歉,这太令人困惑了,(我的错)
让我尝试再次解释一下,但用一个更简单的例子:

#define a new var and export it to the "env":
export VAR_ONE=thisIsVarOne
# check if it was created:
env | grep VAR_ONE      #this displays: "VAR_ONE=thisIsVarOne"
# use it in a simple echo command:
echo VAR_ONE=$VAR_ONE  #this displays: "VAR_ONE=thisIsVarOne"

# create a new var with the name that contains the value of VAR_ONE ("newvarthisIsVarOne") in its name:
export newvar${VAR_ONE}="somePrefix${VAR_ONE}"  
# verify if it has been created:
env | grep newvar  # this displays: "newvarthisIsVarOne=somePrefixthisIsVarOne"

现在我的问题是:

我如何使用这个新的综合变量?
请注意: env | grep newvar表明已经创建了一个名为newvar${VAR_ONE}

但我不能地址新变量,例如在 echo 命令中。我尝试过: echo ${newvar${VAR_ONE}}
但这给了我bash: ${newvar${VAR_ONE}}: bad substitution

限制条件:

  1. VAR_ONE 的值可以改变,所以我不能用它来寻址新创建的变量
  2. 我无法使用静态名称声明新变量。为了使用,在脚本中,我需要关键字VAR_ONE作为新创建的变量名称的一部分。变量的名称需要类似于:newvar${VAR_ONE}

预先感谢您 ChriV

答案1

设置:

export VAR_ONE=thisIsVarOne

bash 4.3+可以使用nameref( declare -n):

$ declare -n _var="newvar${VAR_ONE}"            # nameref; define new var name and associate with nameref variable '_var' (can be any valid variable name)
$ _var="somePrefix${VAR_ONE}"                   # assign value to nameref

$ echo "${!_var}"                               # show nameref association
newvarthisIsVarOne

$ echo "${_var}"                                # show value
somePrefixthisIsVarOne

$ echo "${newvarthisIsVarOne}"                  # explicitly reference new variable by name
somePrefixthisIsVarOne

答案2

设置:

export VAR_ONE=thisIsVarOne

使用关联数组的替代方案:

$ unset      newvar
$ declare -A newvar

$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"

$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )

$ echo "${newvar[${VAR_ONE}]}"
somePrefixthisIsVarOne

在评论中,OP 指出需要引用多个变量,例如newvar${VAR_ONE}newvar${OTHER_VAR}newvar${ANOTHER_VAR}

只要 3 个变量(VAR_ONEOTHER_VARANOTHER_VAR)具有不同的值,这种使用关联数组的方法就可以工作。价值观,否则重复值将导致创建单个数组条目(最新的赋值会覆盖先前的赋值)。

如果这3个变量可以有相同的价值那么另一种方法是使用文字作为关联数组的索引,例如:

#### instead of:

$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"

$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )

#### we use:

$ newvar[VAR_ONE]="somePrefix${VAR_ONE}"

$ typeset -p newvar
declare -A newvar=([VAR_ONE]="somePrefixthisIsVarOne" )

答案3

不要使用 a$来影响 bash 中的变量:

var_name=value
var_name1="value with spaces"
var_name2='value with $ or special characters'

要获取变量的值,请$在其名称前使用 a:

echo "var_name=$var_name"
echo "var_name1=use_braces_to_protect_the variable_name_${var_name1}_"
my_new_var="$var_name2"

如果您的变量包含另一个变量的名称,则必须在变量名称之前使用感叹号并将其放入大括号中:

my_var=spam
the_var_name=my_var
echo "the value is '${!the_var_name}'"

所以你的程序将是:

#! /bin/bash

VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)

echo "VAR_NAMES=" "${VAR_NAMES[@]}"

for VAR_NAME in "${VAR_NAMES[@]}"; do
    echo
    echo "VAR_NAME=$VAR_NAME"

    NEW_VAR_NAME="newvar$VAR_NAME"
    echo "NEW_VAR_NAME=$NEW_VAR_NAME"

    export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
    echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"
done

更新

您还可以使用新的 var_name/var_value 作为键/值创建哈希表(关联数组):

#! /bin/bash

VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)

echo "VAR_NAMES=" "${VAR_NAMES[@]}"

declare -A NEW_VAR_NAMES=()

for VAR_NAME in "${VAR_NAMES[@]}"; do
    echo
    echo "VAR_NAME=$VAR_NAME"

    NEW_VAR_NAME="newvar$VAR_NAME"
    echo "NEW_VAR_NAME=$NEW_VAR_NAME"

    export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
    echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"

    NEW_VAR_NAMES+=(["${NEW_VAR_NAME}"]=${!NEW_VAR_NAME})
done

echo
echo "${NEW_VAR_NAMES[@]@A}"

for new_var_name in "${!NEW_VAR_NAMES[@]}"; do
    echo "new_var_name is ${new_var_name} and its content is '${NEW_VAR_NAMES[$new_var_name]}'"
done

答案4

要访问一个变量而不使用单独的变量(对于${!pointer}语法或 nameref)唯一的解决方案是使用eval,例如

eval "echo \$newvar$VAR_ONE"

——但如果你犯了错误,这就是危险的,实际上所有人类都会犯错误。

环境多变的创建后export,您可以使用子进程来进行查找。特别awk是 POSIX,通常出现在最多系统具有bash

    awk -v name=newvar$VAR_ONE 'BEGIN{printf "%s",ENVIRON[name]}'
    # or simpler {print ENVIRON[name]} adds newline which may be okay,
    # e.g. if you use this in $(...) or `...` which removes newline
    # or _instead of_ an echo command because echo also adds newline

更简单的是,许多系统都有printenv并且您可以这样做printenv newvar$VAR_ONE- 这也会添加换行符。

相关内容