抱歉,这太令人困惑了,(我的错)
让我尝试再次解释一下,但用一个更简单的例子:
#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
限制条件:
- VAR_ONE 的值可以改变,所以我不能用它来寻址新创建的变量
- 我无法使用静态名称声明新变量。为了使用,在脚本中,我需要关键字
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_ONE
、OTHER_VAR
和ANOTHER_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
- 这也会添加换行符。