局部变量实现

Local variables implementation

我使用 fish shell 有一段时间了,最​​近我与一位同事就局部变量进行了交谈。显然,Bash 不支持局部变量,仅使用环境变量在进程之间传递动态数据。局部变量是否也只是环境变量,但有一些额外的东西?我很好奇鱼是如何创造这种行为的。

Bash doesn't support local variables

事实并非如此。 Bash(和其他 shells,包括破折号——它是它拥有的少数 POSIX 扩展之一)有 local 关键字来创建局部变量。它们只是默认为全局,而 fish 默认为本地。

此外,当您说 "environment variables" 时,您的意思是 "exported" 变量,这需要在 posxy shells 中明确 "export" 步骤,以及“-x”或“--export”标志到 set in fish.

我是。这里有两件不同的事情在起作用——这个变量是否只在这个 function/block/whatever 中可用,而不是在外部可用,以及它是否传递给 children,包括外部进程.

Are local variables also just environment variables, but with something extra?

Non-exported 变量。它们没有提供给 OS 的 setenv 函数,因此它不会将它们复制到子进程。

块结束时删除局部变量。实际上,这可以通过将它们放在堆栈上并 "popping" 顶部来很好地完成。

请注意,至少在鱼类中,这些概念是完全正交的:

您可以有 local-exported 个变量(使用 set -lx),它们将被传递给外部命令并复制到函数(因此它们会得到自己的本地版本),但会被删除当功能结束时。这些对于临时更改某些内容很有用 - 例如为函数设置 $PATH,或者在调用某些东西时覆盖 $EDITOR。

并且你可以有global-unexported个变量,这些变量可以被函数访问但不能被外部命令访问。这些对于 shell 设置很有用,例如 $fish_function_path,它对外部工具或 $COLUMN 没有用,如果导出它甚至可能破坏外部工具(因为它们开始读取它而不是检查终端尺寸本身)。

这里好像有一些误解:

  • bash 可以有函数的局部变量:https://www.gnu.org/software/bash/manual/bash.html#index-local
  • 并非每个 shell (bash/fish/etc) 变量都在环境中。这就是存在 export(bash)和 set -x(鱼)命令的原因。
  • 要让两个独立的进程共享同一个变量值,您必须通过环境传递它们。环境是将 shell 变量暴露给其他进程的方式。