以另一個使用者身份啟動腳本
我在 /etc/init.d/ 中創建了一個腳本,它必須從其他(非 root 特權)使用者的主目錄執行其他幾個腳本,就像他們啟動它們一樣。
我使用以下命令啟動這些腳本:
sudo -b -u <username> <script_of_a_particular_user>
它有效。但是對於每個繼續執行的使用者腳本(例如一些看門狗),我看到一個相應的父 sudo 程序,仍然活著並以 root 身份執行。這會在活動程序列表中造成混亂。
所以我的問題是:如何從現有的 bash 腳本作為另一個使用者啟動(fork)另一個腳本並將其保留為孤立(獨立)程序?
更詳細的解釋:
我基本上試圖通過執行在其主目錄中的相應子目錄中找到的執行檔(名為 .startUp 和 .shutDown)來向機器上的其他使用者提供一種在系統啟動或系統關閉時執行東西的方法。由於我沒有找到任何其他方法來執行此操作,因此我編寫了完全執行此操作的 bash 腳本,並且我已將其配置為 /etc/init.d/ 中的服務腳本(通過遵循骨架範例),因此當它執行時使用 start 參數,它從 .startUp 目錄啟動所有內容,當它使用 stop 參數執行時,它從所有使用者的 .shutDown 目錄啟動所有內容。
或者,如果我可以使用一些現有的解決方案來解決這個問題,我也很感興趣。
更新
我環顧四周,發現了這個問題: https ://unix.stackexchange.com/questions/22478/detach-a-daemon-using-sudo
那裡接受的答案,使用:
sudo -u user sh -c "daemon & disown %1"
,對我有用。但是我也嘗試過沒有disown %1並且是一樣的。所以這就是我所期望的對我有用的東西:sudo -u <username> bash -c "<script_of_a_particular_user> &"
我現在的另一個問題是,為什麼它可以在沒有否認的情況下工作?無論如何,對於某些潛在的特殊情況,我是否仍然應該留下disown電話?
更新 2
顯然這也有效:
su <username> -c "<script_of_a_particular_user> &"
這個呼叫和 sudo 呼叫有什麼區別嗎?我知道這可能是一個完全不同的問題。但是,由於我自己在這裡找到了答案,也許為了這個話題,有人可以在這裡澄清這一點。
更新 3
在我啟動機器後 ,這兩種使用 su 或 sudo 的方法現在都會產生一個新的startpar程序(以 root 身份執行的單個程序)。在程序列表中可見:startpar -f -- <name_of_my_init.d_script>
為什麼會產生這個過程?顯然我做錯了,因為沒有其他 init.d 腳本執行此程序。
更新 4
startpar 的問題已解決。我為此提出了另一個問題:
從 rc.local 或 init.d 啟動程序時 startpar 程序掛起
還有一個問題需要進一步討論非特權使用者的啟動機制:
對此的正確答案是,為了正確的“守護程序”,標準輸入、標準輸出和標準錯誤需要重定向到 /dev/null (或一些真實文件):
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。
這本質上正是Debian dpkg的 start-stop-daemon實用程序的核心。這就是為什麼我更喜歡以這種方式啟動腳本,而不是在我的程式碼中引入另一個外部實用程序呼叫。start-stop-daemon在您需要啟動完整的守護程序並且您需要start-stop-daemon 提供的附加功能的情況下很有用(例如檢查指定的程序是否已經在執行,以便它不會不要再次啟動它)。
還值得注意的是,您還可以關閉程序的文件描述符,而不是將它們重定向到**/dev/null**,例如:
su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"
**0<&-**關閉標準輸入(0)
**1>&-**關閉標準輸出(1)
**2>&-**關閉標準錯誤(2) 輸出
< > 符號的方向無關緊要,只要指定了長文件描述符編號。所以這同樣好:
su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"
或者
su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"
然而,有一個更短的方法來寫,沒有標準輸入和標準輸出的數字,其中方向確實很重要:
su someuser -c "some_script.sh <&- >&- 2>&- &"
當文件描述符關閉或重定向到 /dev/null (start-stop-daemon正在重定向到 /dev/null )時,該程序可以安全地作為守護程序在後台執行。這就是避免在啟動期間啟動腳本出現問題( startpar )所需要的。
我已經從我最初的想法中實現了整個解決方案並將其放在 GitHub 上: