对变量的赋值打印在 zsh 脚本的 stdout 上

eri*_*cbn 6 shell zsh

这是一个重现问题的示例脚本:

例子.zsh

zmodules=(foo bar/baz)

local zmodule
for zmodule (${zmodules}); do
  local zurl zname
  zname=${zmodule##*/}
  case ${#zmodule//[^\/]/} in
    0) zurl="https://github.com/foo/${zmodule}" ;;
    1) zurl="https://github.com/${zmodule}" ;;
  esac
  print "${zurl} ${zname}"
done
Run Code Online (Sandbox Code Playgroud)

当前运行脚本的结果:

$ source ./example.zsh 2>/dev/null
zmodule=bar/baz
zurl=https://github.com/bar/baz
zname=baz
https://github.com/foo/foo foo
zurl=https://github.com/foo/foo
zname=foo
https://github.com/bar/baz baz
Run Code Online (Sandbox Code Playgroud)

预期结果:

$ source ./example.zsh 2>/dev/null
https://github.com/foo/foo foo
https://github.com/bar/baz baz
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

编辑:我想我明白了:local只能在函数内部使用。但是为什么在我声明局部变量时仍然打印赋值?

Pes*_*The 6

这是因为您localfor循环中重复执行。来自man zshbuiltins

local

与 相同typeset,除了...

typeset

设置或显示外壳参数的属性和值。

因此,执行local var没有任何赋值)将导致zsh显示该变量的属性和值(如果它已经存在)。请参阅此代码段演示该行为:

$ local var
$ var=10
$ local var
var=10
$ local var=15
$ local var2=20 var
var=15
Run Code Online (Sandbox Code Playgroud)

旁注:您可能会问为什么要打印两个作业,而在我的示例中,第一个local不打印任何内容。那是因为您正在使用source来运行脚本,所以变量已经从您之前的尝试中设置了。