Bashとzshの二重および三重置換

Bashとzshの二重および三重置換

後続のバックエンド部分この問題

Iは二重交換bashに使用できます。どちらの場合も、旧式(hack-y)が機能します。${!FOO}zsh ${(P)FOO}eval \$$FOO

だから私にとって最も賢明で最も論理的なのは、${${FOO}}, ${${${FOO}}}…二重/三重/n置換です。なぜ期待どおりに動作しないのですか?

第二:ステートメント\の機能は何ですかeval?警察アウトで仕事がeval \$$$FOO不可能になると思います。すべてのシェルで動作するトリプル/ n置換をどのように使用できますか?

答え1

(現在のプロセスID)の拡張を\防ぐために使用する必要があります。$$トリプル置換の場合は二重評価が必要であるため、各評価で不要な拡張を避けるために、より多くのエスケープが必要です。

#! /bin/bash
l0=value
l1=l0
l2=l1
l3=l2
l4=l3

echo $l0
eval echo \$$l1
eval eval echo \\$\$$l2
eval eval eval echo \\\\$\\$\$$l3
eval eval eval eval echo \\\\\\\\$\\\\$\\$\$$l4

答え2

#!/bin/bash

hello=world
echo=hello

echo $echo ${!echo}

答え3

値がFOO有効な変数名(例BAR:)と仮定し、eval \$$FOO値をBAR別々の単語に分割し、各単語をワイルドカードパターンとして処理し、結果の最初の単語をコマンドとして実行し、別の単語を引数として渡します。 。ドルの前のバックスラッシュは文字通り処理されるため、組み込みeval関数に渡される引数は4文字の文字列です$BAR

${${FOO}}文法エラーです。一般的なシェルにはそのような機能がないため、「二重置換」は実行されません(この構文はとにかく使用されません)。 zshでは${${FOO}} はいそれは動作し、二重代替ですが、あなたが望むものとは異なる方法で動作します。 valueに対して2回の連続変換を実行します。FOOどちらもID変換なので、これを書くのは素晴らしい方法です${FOO}

変数の値を変数として扱うには、正しく引用する必要があります。結果を変数に設定すると、はるかに簡単になります。

eval "value=\${$FOO}"

答え4

なぜこれを行うべきですか?

次のようないくつかの手順でいつでもこれを行うことができます。

eval "l1=\${$var}"
eval "l2=\${$l1}"
...

または、次の機能を使用してください。

deref() {
  if [ "$1" -le 0 ]; then
    eval "$3=\$2"
  else
    eval "deref $(($1 - 1)) \"\${$2}\" \"\$3\""
  fi
}

それから:

$ a=b b=c c=d d=e e=blah
$ deref 3 a res; echo "$res"
d
$ deref 5 a res; echo "$res"
blah

FWIW、住所zsh

$ echo ${(P)${(P)${(P)${(P)a}}}}
blah

関連情報