macOS终端zsh中set与unset命令未按预期工作的问题
zsh中set/unset命令未按预期工作的原因解析
我对这个结果感到十分困惑。
我有两个问题:
- 这是哪里出了问题?
*、@和argv分别是什么?
操作复现(zsh环境)
$ set GITHUB_ENV_var=1 $ echo $GITHUB_ENV_var # ❌ 设置后执行echo无输出 $ set | grep GITHUB_ENV_var '*'=( 'GITHUB_ENV_var=1' ) @=( 'GITHUB_ENV_var=1' ) argv=( 'GITHUB_ENV_var=1' ) $ unset GITHUB_ENV_var # ❌ unset完全不起作用 $ set | grep GITHUB_ENV_var '*'=( 'GITHUB_ENV_var=1' ) @=( 'GITHUB_ENV_var=1' ) argv=( 'GITHUB_ENV_var=1' )
预期结果
$ set GITHUB_ENV_var=1 $ echo $GITHUB_ENV_var 1
一、问题根源
在zsh中,不带选项的set命令作用是设置位置参数(positional parameters),而非定义普通shell变量或环境变量。你执行set GITHUB_ENV_var=1时,只是把字符串GITHUB_ENV_var=1赋值给了位置参数集合,根本没有创建名为GITHUB_ENV_var的变量:
echo $GITHUB_ENV_var无输出:因为该变量从未被定义unset GITHUB_ENV_var无效:目标变量不存在,自然无法unset
若要定义普通shell变量,直接执行GITHUB_ENV_var=1即可;若需定义环境变量,再加上export前缀(即export GITHUB_ENV_var=1),这和你已知的用法一致。
二、*、@和argv的含义
这三个都是zsh中与位置参数相关的特殊变量:
$*:代表所有位置参数的集合,默认会将所有参数拼接为单个字符串(分隔符由IFS环境变量控制)$@:同样代表所有位置参数的集合,但在双引号包裹时会保留每个参数的独立性(例如"$@"会将每个参数作为单独字符串处理)argv:zsh特有的数组变量,与$@等价,直接通过argv可访问所有位置参数组成的数组,比如argv[1]对应第一个位置参数
你执行set GITHUB_ENV_var=1后,这三个变量均被设置为包含GITHUB_ENV_var=1的集合,因此grep能查到对应内容。若要清空位置参数,执行set --即可重置$*、$@和argv为空。
内容的提问来源于stack exchange,提问作者xgqfrms
相关产品推荐
相关产品推荐

