mrjayviper Asked: 2019-03-04 03:03:24 +0800 CST2019-03-04 03:03:24 +0800 CST 2019-03-04 03:03:24 +0800 CST zsh:如何根据另一个变量获取变量的值? 772 我认为一个例子最能解释我需要什么 _v1="windows" _v2_windows="/mnt/d" _v2_osx="/Volumes/d" echo $_v2_`echo $_v1` 我想回显的值,_v2_windows但_v1用于确定v2要获得两个 s 中的哪一个。 我知道可以使用case语句来解决问题,但我试图避免这种情况。 zsh variable 2 个回答 Voted Best Answer Stéphane Chazelas 2019-03-04T03:49:27+08:002019-03-04T03:49:27+08:00 与zsh: ${(P)varname}展开为名称存储在 中的变量的值$varname。因此,如果$varname包含var,则${(P)varname}扩展为与$var. ${(e)var}扩展为的内容,$var但也执行参数扩展、命令替换和算术扩展。因此,如果$var包含$othervar,则${(e)var}扩展为与$othervar. 您可以嵌套变量扩展运算符,因此可以${(P)${var:-something}}工作 ${:-content}是将参数扩展扩展到任意文本的一种方法(此处content) (详见说明书) 所以你可以这样做: _v1=windows _v2_windows=/mnt/d printf '%s\n' ${(P)${:-_v2_$_v1}} 或者: printf '%s\n' ${(e)${:-\$_v2_$_v1}} 或者分两步完成: varname=_v2_$_v1 printf '%s\n' ${(P)varname} 或者: expansions_to_evaluate=\$_v2_$_v1 printf '%s\n' ${(e)expansions_to_evaluate} 或者您可以使用标准 POSIX 语法: eval 'printf "%s\n" "${_v2_'"$_v1"'}"' 请注意,如果 的值$_v1不受您的控制,所有这些都相当于任意命令注入漏洞,您需要先清理该值。 另请注意,它zsh支持关联数组(并且很久以前bash),因此您可以这样做: typeset -A mnt mnt=( windows /mnt/d osx /Volumes/d ) os=windows printf '%s\n' $mnt[$os] 这将更加清晰易读,并且不会产生任何这些安全隐患。 Kusalananda 2019-03-04T03:48:23+08:002019-03-04T03:48:23+08:00 printf '%s\n' "${(P)$(echo "_v2_$_v1")}" 或者 var=_v2_$_v1 printf '%s\n' "${(P)var}" 在这两种情况下,参数扩展标志(P)都用于将内部${...}名称扩展为我们想要获取其值的实际变量的名称。 这类似于shell${!...}中的变量间接寻址。bash
与
zsh
:${(P)varname}
展开为名称存储在 中的变量的值$varname
。因此,如果$varname
包含var
,则${(P)varname}
扩展为与$var
.${(e)var}
扩展为的内容,$var
但也执行参数扩展、命令替换和算术扩展。因此,如果$var
包含$othervar
,则${(e)var}
扩展为与$othervar
.${(P)${var:-something}}
工作${:-content}
是将参数扩展扩展到任意文本的一种方法(此处content
)(详见说明书)
所以你可以这样做:
或者:
或者分两步完成:
或者:
或者您可以使用标准 POSIX 语法:
请注意,如果 的值
$_v1
不受您的控制,所有这些都相当于任意命令注入漏洞,您需要先清理该值。另请注意,它
zsh
支持关联数组(并且很久以前bash
),因此您可以这样做:这将更加清晰易读,并且不会产生任何这些安全隐患。
或者
在这两种情况下,参数扩展标志
(P)
都用于将内部${...}
名称扩展为我们想要获取其值的实际变量的名称。这类似于shell
${!...}
中的变量间接寻址。bash