我的变量的值为 0,但我没有将其设置为 0

Hap*_*ace 7 zsh variable

今天我注意到我的一个 zsh 函数不起作用;我调查了这个问题,罪魁祸首是:

for i in a b
do
echo "$i"
done
0
0
Run Code Online (Sandbox Code Playgroud)

然后我打开了一个新的 zsh,一切正常:

for i in a b
do
echo "$i"
done
a
b
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释第一个对我来说很奇怪的原因吗?

thr*_*rig 10

% typeset -i i
% for i in a b; print $i
0
0
Run Code Online (Sandbox Code Playgroud)

zsh可以为变量分配各种类型,上面-i是“在内部表示为整数”,这将导致变量被表示为。这也可以通过integer i. 有多种方法可以检查变量是什么:

% print ${(t)i}
integer
% typeset -p i
typeset -i i=0
Run Code Online (Sandbox Code Playgroud)

以及+禁用它的常用 shell (另请参见set -x, set +x):

% typeset +i i
% for i in a b; print $i
a
b
Run Code Online (Sandbox Code Playgroud)

寻找更改该变量类型的原因并将该更改限制在局部范围内(在函数内)可能是有益的,这样全局命名空间就不会被随机类型污染,尤其是在经常使用的一次性变量名称上,例如i. 污染全局命名空间相当容易,因为所需要的只是分配给未声明的变量:

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

% print $g
43
Run Code Online (Sandbox Code Playgroud)

或者有人可以不必要地将-g标志添加到typeset使变量全局的 a 中:

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

导出的变量可能会持续到新进程中(非子壳子进程通过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
Run Code Online (Sandbox Code Playgroud)

  • 据我所知,“脚本”作为一个不同的进程运行,所以不应该受到影响。如果您将随机代码(`.`、`source`、`eval`)采购到现有流程中,那么糟糕的代码很容易污染环境,在这种情况下,您要么不这样做,要么审核每一行随机代码,看看它做什么 (2认同)
  • 我认为你也可以`unset var` 让它失去它可能拥有的任何特殊属性。好吧,除非它也是只读的,在这种情况下,您需要先`typeset +r var`。Bash 和 ksh 可能有相同的问题,变量设置为整数,具有相同的解决方案。除了您不能在其中“取消设置”只读变量。 (2认同)