子Shell和子進程

2020-07-16 10:04:46
Shell 中有很多方法產生子進程,比如以新進程的方式執行 Shell 指令碼,使用組命令、管道、命令替換等,但是這些子進程是有區別的。

子進程的概念是由父進程的概念引申而來的。在 Linux 系統中,系統執行的應用程式幾乎都是從 init(pid為 1 的進程)進程派生而來的,所有這些應用程式都可以視為 init 進程的子進程,而 init 則為它們的父進程。

使用pstree -p命令就可以看到 init 及系統中其他進程的進程樹資訊(包括 pid):
systemd(1)─┬─ModemManager(796)─┬─{ModemManager}(821)
            │                     └─{ModemManager}(882)
            ├─NetworkManager(975)─┬─{NetworkManager}(1061)
            │                       └─{NetworkManager}(1077)
            ├─abrt-watch-log(774)
            ├─abrt-watch-log(776)
            ├─abrtd(773)
            ├─accounts-daemon(806)─┬─{accounts-daemon}(839)
            │                        └─{accounts-daemon}(883)
            ├─alsactl(768)
            ├─at-spi-bus-laun(1954)─┬─dbus-daemon(1958)───{dbus-daemon}(1960)
            │                         ├─{at-spi-bus-laun}(1955)
            │                         ├─{at-spi-bus-laun}(1957)
            │                         └─{at-spi-bus-laun}(1959)
            ├─at-spi2-registr(1962)───{at-spi2-registr}(1965)
            ├─atd(842)
            ├─auditd(739)─┬─audispd(753)─┬─sedispatch(757)
            │               │                └─{audispd}(759)
            │               └─{auditd}(752)
本教學基於 CentOS 7 編寫,CentOS 7 為了提高啟動速度使用 systemd 替代了 init。CentOS 7 之前的版本依然使用 init。

Shell 指令碼是從上至下、從左至右依次執行的,即執行完一個命令之後再執行下一個。如果在 Shell 指令碼中遇到子指令碼(即指令碼巢狀,但是必須以新進程的方式執行)或者外部命令,就會向系統核心申請建立一個新的進程,以便在該進程中執行子指令碼或者外部命令,這個新的進程就是子進程。子進程執行完畢後才能回到父進程,才能繼續執行父指令碼中後續的命令及語句。

子Shell和子進程