shell 如何决定运行同名关键字、内置命令和外部命令中的哪一个?

shell 如何决定运行同名关键字、内置命令和外部命令中的哪一个?

当存在同名内置命令、关键字和/或外部命令时,Bash shell 决定运行哪个命令的顺序是什么?

例如,

  • 关键字time和外部命令time
  • coreutils 的内置printf和外部命令printf

答案1

来自GNU Bash 参考手册:

将命令拆分为单词后,如果生成简单命令和可选参数列表,则将执行以下操作。

  1. 如果命令名称不包含斜杠,shell 会尝试查找它。如果存在具有该名称的 shell 函数,则按如下所述调用该函数外壳函数

  2. 如果名称与函数不匹配,shell 会在 shell 内置函数列表中搜索它。如果找到匹配项,则调用该内置函数。

  3. 如果名称既不是 shell 函数也不是内置函数,并且不包含斜杠,Bash 将搜索$PATH包含该名称的可执行文件的目录的每个元素。 Bash 使用哈希表来记住可执行文件的完整路径名,以避免多次PATH搜索(请参阅Bourne Shell 内置函数)。$PATH仅当在哈希表中未找到该命令时,才会对中的目录执行完整搜索。如果搜索不成功,shell 会搜索名为 的已定义 shell 函数command_not_found_handle。如果该函数存在,则使用原始命令和原始命令的参数作为其参数来调用该函数,并且该函数的退出状态将成为 shell 的退出状态。如果未定义该函数,shell 将打印一条错误消息并返回退出状态 127。

  4. 如果搜索成功,或者命令名称包含一个或多个斜杠,则 shell 会在单独的执行环境中执行指定的程序。参数 0 设置为给定的名称,命令的其余参数设置为提供的参数(如果有)。

  5. 如果由于文件不是可执行格式且文件不是目录而导致此执行失败,则假定它是 shell 脚本,并且 shell 会按照中所述执行它外壳脚本

  6. 如果命令不是异步开始的,shell 会等待命令完成并收集其退出状态。

答案2

如果发生名称冲突,bash 将首先尝试调用内置命令。我做了以下测试。

time sleep 100 &
ps -ef | grep [t]est

外部命令应该创建新进程,但您会看到没有结果。这意味着调用了内置命令。

相关内容