bash 使用什么顺序来决定是使用别名、函数、内置函数还是可执行文件?

Sha*_*hop 3 bash

在 bash 中可以定义函数和别名,并且 bash 有自己的内置函数。此外,bash 可以运行系统上可用的可执行文件。

为了解决这个问题,假设 shell(无论是交互式还是非交互式)启用了别名扩展。

如果用户定义的函数与可执行文件同名,bash 会运行该函数还是可执行文件?

如果用户定义的函数与 bash 内置函数同名,那么 bash 会运行该函数还是内置函数?

等等 - 如果有两个(或更多)具有相同标识符的事物,bash 将运行的优先顺序是什么?

Sha*_*hop 5

优先级

首先,仅当 shell 处于交互模式或expand_aliases使用 设置 shell 选项时shopt,如果匹配的别名存在,则简单命令的第一个单词将被替换为匹配的别名。1

接下来,bash 将按以下顺序检查标识符是否定义为以下之一,并在找到第一个匹配项后执行命令:

  1. 如果命令名包含斜杠,shell会尝试执行命令名指示的路径
  2. 如果存在具有所提供名称的 shell 函数,则调用该 shell 函数
  3. 如果存在具有所提供名称的 shell 内置命令,则调用该 shell 内置命令
  4. 如果命令名在 bash 记住的命令的哈希表中,bash 将尝试执行哈希表中的路径(如果该路径不再有效,bash 将不会尝试搜索其PATH
  5. 如果命令名称不在 bash 的哈希表中,bash 将搜索与其中的名称匹配的可执行文件,按顺序PATH搜索其目录,并执行它找到的第一个这样的可执行文件PATH
  6. 如果搜索不成功,bash 将调用该command_not_found_handle函数(如果已定义)
  7. 否则,bash 打印一条错误消息并返回退出状态 127

控制 bash 使用的内容

要强制 bash 使用内置函数而不是扩展别名或调用同名函数,请使用builtin内置函数。

要强制 bash 使用内置函数或在 中找到的可执行文件PATH而不是使用别名或函数,请使用command内置函数。

要强制 bash 使用磁盘上的可执行文件,请使用可执行文件的路径(如果已知),或者使用type -P <executable_name>获取路径,然后使用该路径调用可执行文件。

要删除别名,请使用unalias. 要删除函数,请使用unset.

要从 bash 的哈希表中删除条目,请使用hash -d <name>. 要查看 bash 哈希表中条目存储的路径,请使用hash -t <name>。(当哈希表存储不再指向所需可执行文件的旧路径时,这有助于调试。)

更多信息/文档

有关详细信息,请参阅bash 手册页(尤其是命令执行部分)或GNU bash 手册


1说交互式 bash shell总是扩展别名有点过于简单化,因为可以在交互式 shell 中使用shopt. 只是交互式 bash shell 默认是扩展别名的。