從 rc.local 或 init.d 啟動程序時,startpar 程序掛起
從完整的 init.d 腳本(SysV 樣式)或從 rc.local 文件的簡單單行呼叫開始進行中的(類似服務的)程序時,我遇到了一個特殊的問題,如下所示:
su someuser -c "/home/someuser/watchdog.sh &"
watchdog.sh 包含以下內容:
#!/bin/bash cd /home/someuser until ./eventMonitoring.py do echo "Program crashed with exit code $?. Starting again..." >&2 sleep 1 done
我總是在程序列表中留下一個額外的程序:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
如果我從我的 init.d 腳本啟動它(來源:https ://github.com/ivankovacevic/userspaceServices )
我得到了相同的過程,但它是startpar -f – userspaceServices
這個過程是什麼鬼?為什麼在查看 startpar 的手冊頁時沒有提到**-f參數?**在以另一個使用者身份在啟動時啟動程序方面我做錯了什麼,這個奇怪的 startpar 程序也需要保留(或啟動)?為什麼任何其他 init.d 腳本都不存在該程序?
有人可以幫我解釋一下這個問題嗎?
注意:我的系統是 Debian Wheezy 7.4.0
更新 !
我在 stackoverflow 上提出了一個新問題,從程序員的角度討論startpar行為:
https ://stackoverflow.com/questions/22840360/figuring-out-what-startpar-c-sysvinit-is-doing
我對此的進一步調查使我找到了解決方案。所以現在我知道如何正確地做到這一點,但我仍然不明白為什麼startpar 的行為如此。因此,如果有人願意介入並解釋這一點,我更願意接受這個答案而不是這個答案。
基本上問題是我呼叫腳本時沒有將標準輸入、標準輸出和標準錯誤重定向(或關閉)到文件或 /dev/null 並且出於某種原因startpar(“用於並行執行多個執行級腳本” ) 程序,據我了解,它是在啟動期間啟動其他程序的程序,因此在我的這個腳本上被阻止。它確實啟動了我的腳本,但它本身並沒有完成執行,而是停留在程序列表中顯示的階段:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD root 3048 1 0 1024 620 1 20:04 ? 00:00:00 startpar -f -- rc.local
startpar的原始碼在這裡:http ://svn.savannah.nongnu.org/viewvc/startpar/trunk/startpar.c?root=sysvinit&view=markup
我瀏覽了一下,並在我發佈在 stackoverflow 上的一個新問題中進行了初步分析。在我在這裡添加到我的問題的更新中找到連結。
我使用的最終解決方案是:
su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"
su - 將使用者身份替換為someuser
-c - su 參數以執行指定的命令
nohup - 執行不受掛斷影響的命令。防止父程序終止子程序的情況。在這裡添加以防萬一。但實際上對我的特定情況沒有影響。是否需要取決於環境(檢查shopt)
>/dev/null - 將標準輸出重定向為空,基本上禁用它。
2>&1 - 將標準錯誤 (2) 輸出重定向到標準輸出 (1),它被重定向到 null
& - 分離到後台,這會將標準輸入也重定向到 /dev/null。
查看在我的系統上執行的其他已知守護程序的文件描述符,我發現重定向到 /dev/null 是很常見的事情。而且只有一些守護程序實際上完全關閉了標準輸入、標準輸出、標準錯誤。例如,可以通過以下方式實現:
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
在實際意義上,它們都是一樣的,並且需要(任一選項)將程序乾淨地分離為後台守護程序。