zsh:如何根据另一个变量获取变量的值?

mrj*_*per 5 zsh variable

我认为一个例子最能解释我需要什么

_v1="windows"

_v2_windows="/mnt/d"
_v2_osx="/Volumes/d"

echo $_v2_`echo $_v1`
Run Code Online (Sandbox Code Playgroud)

我想回应_v2_windows但使用的值_v1来确定v2要获取两个s 中的哪一个。

我知道可以使用case语句来解决问题,但我试图避免这种情况。

Sté*_*las 8

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}}
Run Code Online (Sandbox Code Playgroud)

或者:

printf '%s\n' ${(e)${:-\$_v2_$_v1}}
Run Code Online (Sandbox Code Playgroud)

或者分两步完成:

varname=_v2_$_v1
printf '%s\n' ${(P)varname}
Run Code Online (Sandbox Code Playgroud)

或者:

expansions_to_evaluate=\$_v2_$_v1

printf '%s\n' ${(e)expansions_to_evaluate}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用标准的 POSIX 语法:

eval 'printf "%s\n" "${_v2_'"$_v1"'}"'
Run Code Online (Sandbox Code Playgroud)

请注意,如果 的值$_v1不在您的控制之下,所有这些都相当于任意命令注入漏洞,您需要先清理该值。

另请注意,zsh支持关联数组(并且很久以前就有bash),因此您可以执行以下操作:

typeset -A mnt
mnt=(
  windows /mnt/d
  osx     /Volumes/d
)
os=windows
printf '%s\n' $mnt[$os]
Run Code Online (Sandbox Code Playgroud)

这将更加清晰,并且不会产生任何安全隐患。