cri*_*ron 14 ls cd-command fork
为什么ls
需要一个单独的进程来执行?我知道为什么像这样的命令cd
不能通过分叉机制执行,但是如果ls
不分叉就执行有什么危害吗?
Chr*_*own 18
答案或多或少ls
是外部可执行文件。您可以通过运行查看它的位置type -p ls
。
那么为什么不ls
内置到外壳中呢?嗯,为什么会这样?shell 的工作不是包含所有可用的命令,而是提供一个能够运行它们的环境。一些现代 shell 具有echo
, printf
, 和它们的同类作为内置函数,它们在技术上不必是内置函数,但是当它们重复运行时(主要是在紧密循环中)出于性能原因而这样做。如果不将它们内置,shell 将不得不为每次调用它们分叉并执行一个新进程,这可能会非常慢。
至少,运行ls
外部可执行文件需要运行 exec 系列系统调用之一。您可以在不分叉的情况下执行此操作,但它会替换您正在使用的主 shell。您可以通过执行以下操作来查看该实例中发生的情况:
exec ls; echo "this never gets printed"
Run Code Online (Sandbox Code Playgroud)
由于您的 shell 的进程映像已被替换,执行此操作后将无法再访问当前的 shell。为了使 shell 在运行 ls 后能够继续运行,必须将命令内置到 shell 中。
Forking 允许替换不是您的主 shell 的进程,这意味着您可以在之后继续运行您的 shell。
Jon*_*ham 15
该猛砸参考手册状态:
内置命令是实现单独实用程序不可能或不方便获得的功能所必需的。
也就是说,shell 被设计为仅包含内置命令,如果:
该ls
命令不符合上述任何要求。
但是,这里没有阻止ls
作为内置程序实现的编程约束 ,它与 bash 解释器在同一进程中执行。命令没有被实现为 shell 内置命令的设计原因是:
关于第一个原因 - 您希望外壳尽可能独立且具有弹性。您不希望 shell 卡在ls
“未响应仍在尝试”的 NFS 安装上。
关于第二个原因 - 在许多情况下,您可能希望将 shell 用于使用 Busybox 或其他具有不同ls
实现的文件系统的系统。或者甚至在具有不同ls
实现的操作系统中使用相同的 shell 源。
关于第三个原因 - 对于诸如find . -type d | xargs ls -lad
很难或不可能ls
在与 shell 解释器相同的进程中实现的表达式。
关于第四个原因 - 某些ls
命令可能需要很长时间才能完成。在此期间,您可能希望 shell 继续执行其他操作。