Linux的終端與進程
Linux的普通進程(守護進程除外) 是終端的子進程,進程的存在要依賴終端為其提供空間包括標準輸入、標準輸出、標準出錯。比如,在ssh的客戶端啟動一個連入linux的終端,運行pstree命令,可以看到如下結果:

可以看到pstree相當于當前終端啟動的一個子進程。
然后,我們在輸入sleep 2000 &命令,讓終端啟動一個在后臺運行的sleep進程,接下來再運行pstreee;

可以看到,啟動了一個pid為1354的進程,然后該進程的父進程為sshd,也就是ssh服務啟動的終端;
然后,在/proc/1354/fd下,可以看到如下內容:

其中的0、1、2分別指標準輸入、標準輸出和標準出錯,并且它們都指向了/dev/pts/0;
這里的pts是指:pseudo-terminal slave,是虛擬終端的一種實現方式,0是虛擬終端的編號。可以輸入ll /dev/pts/看一下結果:

從中可以看出在/dev/pts目錄下,一共有3個虛擬終端正在運行。
現在回到虛擬機上的終端界面,也就是X系統上的終端,也在后臺運行一個sleep,再進到這個進程所對應的fd目錄下,可以看到如下結果:

這里的標準輸入、標準輸出和標準出錯指向了/dev/tty1,tty是真正的終端,pts則是對它的虛擬。
在進程運行過程中(即使是后臺運行的進程),當終端退出時,進程將會收到SIGHUP信號,如果程序沒有對這種信號進行捕獲處理,進程默認就會退出。還以剛才那個在虛擬終端中后臺運行的sleep為例:

這是,sleep正在運行是的情況,當我把它的終端關閉后,情況為:

bash少了一個,并且sleep沒有了。
因為關閉了一個ssh的虛擬終端,自然會少一個bash,同時在作為該終端子進程的sleep也同時退出了。
那如何讓一個程序在終端退出后繼續工作呢?
首先一個明確的思路是,可以將要啟動的進程的父進程設為init,這樣不過當前的終端怎么樣,都不會影響進程的運行。可以這樣:
setuid ping localhost > /dev/null &
或者
( ping localhost > /dev/null &)

可以看出,ping直接成為init的子進程了。
另外,也可以用nohup命令來實現。
【編輯推薦】
- Ubuntu系統下實現終端嵌入桌面
- Linux進程與作業的區別及相關命令
- Linux十大妙用:充當Windows修復工具
- Linux/Unix操作系統處于內網的桌面控制
- 紅帽在Linux桌面系統領域的未來——SPICE





























