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 秒)。

相關內容