exec bash 内置内部如何工作?

exec bash 内置内部如何工作?

链接 我得到以下有关 exec bash 内置命令的信息:

如果提供命令,则更换外壳无需创建新进程。

它到底是如何替代shell的(即它内部是如何工作的)?系统调用的工作方式是否exec*()相同?

答案1

是的,内置函数最终使用了系统调用系列exec之一。exec*()正常运行命令也是如此。只是当你使用时exec,它并没有先使用fork()系统调用来创建新的进程,结果就是新的命令取代了shell。

答案2

strace在一个正在运行的bash实例上做了一个。然后我调用了命令exec sleep 100。现在看看发生了什么:

access("/bin/sleep", X_OK)              = 0
...
execve("/bin/sleep", ["sleep", "100"], [/* 14 vars */]) = 0
...
nanosleep({100, 0},
...
exit_group(0)                           = ?

sleep所以你可以看到,它几乎与你调用正常方式时发生的情况相同。bash检查系统调用是否授予可执行权限( X_OK) 。然后执行文件名指向的程序。系统调用之后,拥有对进程的控制权。它的事情:。它还保持相同的 pid。结束后该过程也结束。是否不再运行。/bin/sleepaccess()execve()execve()sleepnanosleep()sleepsleepbash

证据:

在另一个窗口中,我用 观看了整个过程ps。在运行该命令之前,它看起来像这样:

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 -bash

并在运行时:

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 sleep 100

结束后sleep该进程就消失了。

当我正常运行时发生了什么?

access("/bin/sleep", X_OK)              = 0
...
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c9fd089d0) = 19261
...
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 19261
...
--- SIGCHLD (Child exited) @ 0 (0) ---

检查执行权限。然后创建一个子进程clone()。该bash实例现在位于后台进程组,sleep现在位于前台进程组。最后,调用wait4()等待子进程结束(需要 100 秒)。

相关内容