Zsh、evalなしで間接配列変数を割り当てる

Zsh、evalなしで間接配列変数を割り当てる

VARNAME他の変数の名前を含む変数があります。私はそれを使用せずに他の変数に割り当てたいと思いますeval。どうすればいいですか?

使いたくない理由evalは次のとおりです。まず、変数を前に追加する関数を想定しますfoo

% prepend_foo() { foo=("$@" $foo) }
% foo=(1 2)
% print -l $foo
1
2
% prepend_foo x 'a b c' y
% print -l $foo
x
a b c
y
1
2
%

それでは、変数に添付されている一般的な関数を考えてみましょう。

% prepend() { var=$1; shift; eval "$var=($@ ${(P)var})" }
% foo=(1 2)
% print -l $foo
1
2
% prepend foo x 'a b c' y
% print -l $foo
x
a
b
c
y
1
2
%

ご覧のように、空白のある変数は複数の配列項目に分割されます。私が望むことを達成するために引用符を正しく組み合わせることはできません。


IRCでは誰かが使用を提案しましたが、${name::=word}これは配列では機能しません。

21:23 < someone> > b=(bar baz); a=b; : ${(P)a::=(foo ${(P)a})}; typeset -p b
21:23 < machabot> someone: typeset b='(foo bar baz)'
21:23 < someone> dammit that's a string

ベストアンサー1

配列に要素を追加するには、次のようにします。

a[1,0]=(more elements)

またはこれを行うこともできます:

a=(more elements "$a[@]")

以下を行います。

a=(more elements $a)

の空の要素は削除されます$a

これを行うための関数を作成することが目的ですが、eval構文が正しいことを確認する必要があります。

prepend() {
  eval "${1}[1,0]"='("${@[2,-1]}")'
}

("${@[2,-1]}")文字通りに渡されるように.を一重引用符で囲む方法を確認してくださいeval

またはより長い方法ですが、動作しませんprepend var more elements(変数名がある場合var)。

prepend() {
  local var=$1; shift
  eval "$var"='("$@" "${'"$var"'[@]}")'
}

eval評価するコードはprepend varname ...次のとおりです。

 varname=("$@" "${varname[@]")

"$@"に渡す前に拡張したくありませんeval$varそこまで拡張するだけです。

変数拡張フラグは、クリーンアップされていないデータと共に使用すると同様に危険ですPeval

var='x[$(uname>&2)0]'
echo "${(P)var}"

コマンドunameが実行されます。

おすすめ記事