Zsh 做实用程序区分

Zsh 做实用程序区分

Zsh 如何区分实用程序/文件是否可执行二进制或脚本,或者只是文件,或 shell 内置等?

答案1

当一个单词出现在命令位置时,zsh 首先检查它是否是一个别名或一个保留字。作为语法分析的一部分,这种情况发生在早期。 Zsh 了解保留字和别名,因为它每个都有一个内部表。此外,如果后缀的形式是.ext存在用 定义的活动后缀别名alias -s ext=…,则以某些后缀结尾的单词将以类似于普通别名的方式扩展。保留字在 zsh 的源代码中是固定的(除了可以禁用)。别名可以在运行时定义。

当 zsh 准备好时执行命令,对于命令位置的单词:

  • 如果该词出现在内表中功能,它作为函数执行。函数可以在运行时定义。
  • 否则,如果该词出现在内表中内置函数。 zsh 的源代码中有一组初始内置函数,但可以通过以下方式定义其他内置函数动态加载的模块
  • 否则,如果auto_cd选项设置后,该单词是目录的路径,并且该命令没有参数,zsh 的行为就像该命令将该cd单词作为参数一样。
  • 否则,zsh 将该单词视为外部命令的名称。它执行一个PATH抬头就像系统功能一样execvp,尽管像大多数 shell 一样 zshexecve直接调用。
  • 如果尝试执行外部命令失败但存在匹配的文件,zsh 可能会尝试间接执行该命令,具体取决于文件的内容:
    • 如果文件以 开头#!,zsh 会读取该行上的解释器路径并尝试调用解释器。这是舍邦机制。在现代系统上,内核会处理这个问题,因此只有在某些古老的系统上才需要实现 zsh。
    • 否则,如果该文件看起来像文本文件,则 zsh 会调用/bin/sh它。此行为是为了向后兼容 shebang 机制存在之前的情况,人们习惯于将 shell 脚本放入命令搜索路径中,然后由sh.
  • 如果这些都无法执行命令,则 zsh 运行该函数command_not_found_handler,如果存在的话。此函数通常用于打印诸如“未找到命令'foo',但可以使用以下命令安装:sudo apt install somepackage”之类的消息,但它也可以尝试以某种不同的方式执行该命令。

相关内容