%20%E5%A6%82%E4%BD%95%E9%81%8B%E4%BD%9C%EF%BC%9F%E4%BD%9C%E7%82%BA%E5%BE%8C%E5%8F%B0%E9%80%B2%E7%A8%8B%E9%81%8B%E8%A1%8C.png)
使進程與終端分離的步驟是什麼?為此我找到了手冊頁daemon()
在描述中,他們提到
如果 nochdir 為零,則 daemon() 將進程的目前工作目錄變更為根目錄(“/”);否則,目前工作目錄保持不變。
如果 noclose 為零,則 daemon() 將標準輸入、標準輸出和標準錯誤重定向到 /dev/null;否則,不會對這些文件描述符進行任何更改。
實際上,我試圖讓我的 python 程式碼作為守護程式運行。我找到了tcollector
代碼這裡。在該程式碼中,他們也遵循與 的描述中相同的步驟daemon()
。所以我的問題是,我們為什麼要執行這些步驟(wrtdaemonize()
在tcollector
)像
為什麼要更改dir
為/
、umask
to022
然後呼叫os.setsid()
等等。
答案1
實際上比您引用的內容更多,但我認為手冊頁可能更清晰。
如果 nochdir 為零,
daemon()
則將進程的目前工作目錄變更為根目錄 (/
)
這裡的假設是該程式是從管理員命令列啟動的,其想法是將守護程式與管理員當時正在執行的操作分開。更改工作目錄以/
防止守護程序使安裝點保持繁忙。例如,如果工作目錄是/home/admin
,一段時間後您想卸載/home
,守護程式會阻止這種情況。
如果 noclose 為零,
daemon()
則將標準輸入、標準輸出和標準錯誤重定向到/dev/null
;
這是為了防止守護程式透過向終端寫入雜散錯誤訊息等來迷惑使用者。守護程序可能應該做的是打開一些(配置的)日誌文件,並在那裡寫入它想要與外部通信的任何內容。
(此函數分叉,如果 fork(2) 成功,則父級呼叫 _exit(2),以便只有子級才能看到更多錯誤。)
再次強調,要與 admins shell 會話解除關聯,主程式會立即返回,而其他部分則留在後台,因此無需明確要求程式在背景啟動(例如./daemon &
)
現在,手冊頁沒有明確說明,但在這裡暗示(在錯誤下):
此函數的 GNU C 函式庫實作取自 BSD,且不採用確保產生的守護程式所必需的雙叉技術(即 fork(2)、setsid(2)、fork(2))。相反,生成的守護程式是會話領導者。
daemon()
還打電話setsid()
從會話中釋放自己控制終端,因此來自終端發送的訊號。但正如引用所述,這留下了一種可能性:如果它打開一個終端設備,它可能會意外地將其作為控制終端。為了避免這種情況,一些程式從子進程調用,fork()
然後setsid()
再次 fork,退出兩個父進程,這樣生成的進程就不是會話領導者(中間的進程是/曾經是),並且無法獲得控制終端。你提到的Python程式正是這樣做的。
更改umask
似乎與守護進程無關。也許該程式對此有特殊的需求。