![shell 如何决定运行同名关键字、内置命令和外部命令中的哪一个?](https://linux22.com/image/87629/shell%20%E5%A6%82%E4%BD%95%E5%86%B3%E5%AE%9A%E8%BF%90%E8%A1%8C%E5%90%8C%E5%90%8D%E5%85%B3%E9%94%AE%E5%AD%97%E3%80%81%E5%86%85%E7%BD%AE%E5%91%BD%E4%BB%A4%E5%92%8C%E5%A4%96%E9%83%A8%E5%91%BD%E4%BB%A4%E4%B8%AD%E7%9A%84%E5%93%AA%E4%B8%80%E4%B8%AA%EF%BC%9F%20.png)
当存在同名内置命令、关键字和/或外部命令时,Bash shell 决定运行哪个命令的顺序是什么?
例如,
- 关键字
time
和外部命令time
, - coreutils 的内置
printf
和外部命令printf
。
答案1
将命令拆分为单词后,如果生成简单命令和可选参数列表,则将执行以下操作。
如果命令名称不包含斜杠,shell 会尝试查找它。如果存在具有该名称的 shell 函数,则按如下所述调用该函数外壳函数。
如果名称与函数不匹配,shell 会在 shell 内置函数列表中搜索它。如果找到匹配项,则调用该内置函数。
如果名称既不是 shell 函数也不是内置函数,并且不包含斜杠,Bash 将搜索
$PATH
包含该名称的可执行文件的目录的每个元素。 Bash 使用哈希表来记住可执行文件的完整路径名,以避免多次PATH
搜索(请参阅Bourne Shell 内置函数)。$PATH
仅当在哈希表中未找到该命令时,才会对中的目录执行完整搜索。如果搜索不成功,shell 会搜索名为 的已定义 shell 函数command_not_found_handle
。如果该函数存在,则使用原始命令和原始命令的参数作为其参数来调用该函数,并且该函数的退出状态将成为 shell 的退出状态。如果未定义该函数,shell 将打印一条错误消息并返回退出状态 127。如果搜索成功,或者命令名称包含一个或多个斜杠,则 shell 会在单独的执行环境中执行指定的程序。参数 0 设置为给定的名称,命令的其余参数设置为提供的参数(如果有)。
如果由于文件不是可执行格式且文件不是目录而导致此执行失败,则假定它是 shell 脚本,并且 shell 会按照中所述执行它外壳脚本。
如果命令不是异步开始的,shell 会等待命令完成并收集其退出状态。
答案2
如果发生名称冲突,bash 将首先尝试调用内置命令。我做了以下测试。
time sleep 100 &
ps -ef | grep [t]est
外部命令应该创建新进程,但您会看到没有结果。这意味着调用了内置命令。