私の変数の値は0ですが、0に設定していません。

私の変数の値は0ですが、0に設定していません。

今日私は私のzsh機能の1つが機能しないことを発見しました。問題を調査した結果、犯人は次のようになります。

for i in a b
do
echo "$i"
done
0
0

その後、新しいzshを開くと、すべてがうまくいきます。

for i in a b
do
echo "$i"
done
a
b

最初の人が私に奇妙に振る舞う理由を説明できる人はいますか?

答え1

% typeset -i i
% for i in a b; print $i
0
0

の変数には、zsh上記の-i「内部的に整数として表示される」さまざまなタイプが割り当てられ、その結果、変数は整数として表示されます。これはを通じて行うこともできますinteger i。変数が何であるかを確認する方法はいくつかあります。

% print ${(t)i}
integer
% typeset -p i
typeset -i i=0

+そしてそれを無効にする共通シェル(図参照set -xset +x

% typeset +i i
% for i in a b; print $i
a
b

特に、頻繁に使用される使い捨て変数名では、グローバル名前空間がランダム型で汚染されないように、変数の型を変更することを見つけて、関数内のローカルスコープに制限することが役立ちます。i宣言されていない変数に割り当てる必要があるため、グローバルネームスペースを汚染するのは非常に簡単です。

% () { local l=42; g=43 }
% print $l

% print $g
43

あるいは、誰かが変数をグローバル変数-gにするために不必要にフラグを追加することもできますtypeset

% () { typeset -g -i h=42 }
% for h in a b; print $h
0
0

エクスポートされた変数は新しいプロセス(を介した非サブシェルの子プロセスまたはを介したfork置換exec)に持続できますが、型は次のことを行いません。

% export -i h=42
% print $h ${(t)h}
42 integer-export

% ( print ${(t)h} )
integer-export

% exec zsh -l
% print $h ${(t)h}
42 scalar-export

関連情報