zsh:他の変数に基づいて変数値を取得するには?

zsh:他の変数に基づいて変数値を取得するには?

私は例が私が必要とするものを最もよく説明すると思います。

_v1="windows"

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

echo $_v2_`echo $_v1`

_v2_windowsエコーしたいのですが、値を使用して_v1どちらを取得するかを決定します。v2

case問題を解決するために宣言を使用することが可能であることを知っていますが、そうしないように努めています。

答え1

そして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}}

または、次の2つのステップを実行してください。

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]

これにより、より明確になり、セキュリティ上のリスクは発生しません。

答え2

printf '%s\n' "${(P)$(echo "_v2_$_v1")}"

または

var=_v2_$_v1
printf '%s\n' "${(P)var}"

どちらの場合も、パラメータ拡張フラグは、内部名を取得したい値を持つ実際の変数の名前に拡張する(P)ために使用されます。${...}

これは似たようなシェル${!...}の変数に間接的に使用されますbash

関連情報