如果此声明错误,请纠正我:zsh 脚本内定义的所有变量/参数在当前 shell 会话中全局保持其持久作用域。
如果上述陈述成立,则可以避免弄乱当前 shell 的环境变量/其他 zsh 脚本。如果可能的话,我们是否应该将 zsh 脚本的所有变量/参数放入匿名/本地内部函数?
可能性可以计算为:
- 我们立即在本地作用域中使用该变量 => 匿名函数
- 通过使用maker
always
=>内部函数来标记它们的范围always
- 标记但使用很少使用的陷阱来标记 => 使用陷阱的内部函数
问题和目的是所有变量/参数都必须是 zsh 脚本中的本地变量/参数,并且在该 zsh 脚本中使用后必须被销毁。
编辑:我确实对运行和获取 shell 脚本感到困惑。
我想要source
脚本中的脚本,但尝试尽量减少源脚本的影响,以扰乱调用脚本的环境。
@Stéphane Chazelas 确实回答了这个问题,但我会按照我的理解说清楚,如果我错了,请纠正。
在 shell 脚本内运行 shell 脚本./script.zsh
将调用新的 shell 来运行该脚本,然后将退出代码返回给调用脚本。
在 shell 脚本中获取 shell 脚本. ./script.zsh
将创建当前 shell 的子进程,并且任何更改 - 定义新变量、函数.. 将被放入当前 shell 的环境中,这是预期的行为,因为大多数用户希望在之后使用它们采购过程,但您可以通过使用评论中提到的@Stéphane Chazelas 等匿名函数来排除不需要的部分。请注意,alias
总是会出现全局范围。
答案1
不,当您执行脚本时,您的 shell 会分叉一个新进程,在该进程中执行该脚本的解释器来解释该脚本的内容。
任何变量赋值只会影响shell变量那外壳调用那过程。一旦该进程终止,调用 shell 的变量将不会受到影响。
我知道的唯一例外是fish
使用 shellset -U var value
来定义fish
通用变量,其中fish
使用某种 IPC 机制在运行的进程之间传递变量值,并在没有进程运行fish
时使用永久存储来保留变量的值。fish
现在当你来源脚本(而不是执行它)与shell 中的.
或内置命令,然后你告诉source
你的shell 来解释该脚本中的代码(这里不涉及子进程,. ./script.zsh
类似于eval "$(<script.zsh)"
)。但你通常只source
在以下情况下使用做希望那里的变量赋值会影响你的 shell,就像当采购环境文件。
现在您可以想象要获取的脚本,其中您想要一些变量,功能,别名...在调用 shell 中定义,但有些只是辅助变量,但并非如此。然后是的,您可以使用具有本地作用域的匿名函数,例如:
myfunc() echo hi # function meant to be defined for the invoker
myvar=value # same for a variable
(){ local i # i variable local
for i in foo bar
alias $i='echo x' # alias defined globally
done
}
(请注意,zsh 仅实现变量和选项的本地作用域,而不是函数、别名......)