從腳本啟動後台程序並在腳本結束時對其進行管理
我想執行和配置一個類似於腳本中的守護程序的程序。
我的 shell 是在 Cygwin 下模擬的 zsh ,守護程序是SFK,一個基本的 FTP 伺服器。
對於這裡重要的事情,腳本
startserv.sh
可以起草如下:#!/bin/sh read -s -p "Enter Password: " pw user=testuser share=/fshare cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share" $cmd &
執行腳本後
startserv.sh
,它會停止(結束?)而不顯示任何提示,然後:
CTRL
+C
結束腳本和後台作業程序;- 擊中
Enter
腳本結束該過程仍然在後台。無論如何,我只能通過
ps
而不能看到它jobs
,所以,當我想關閉程序時,我必鬚髮送一個殘酷的kill -9
信號,這是我想避免的,而贊成CTRL
+C
。另一種方法 是在後台執行整個腳本。‘Would be’,但
read
如果腳本以startserv.sh &
.請注意,我需要一個臨時伺服器,而不是真正的守護程序:也就是說,我希望伺服器程序在腳本結束後在後台執行,以執行簡單的互動式 shell 任務(使用虛擬機來賓),但我沒有t 需要程序在 shell 中存活;因此
nohup
似乎不合適。
擊中
Enter
腳本結束該過程仍然在後台。幾乎!實際上,在您按下 時腳本已經退出
Enter
。但是,這就是您可以恢復提示的方式(因為您的 shell$PS1
會重新列印它)。點擊
Ctrl
+C
終止它們的原因是因為它們兩者是連結的。當你執行你的腳本時,你的 shell 會啟動一個子 shell 來執行它。當您終止此子外殼時,您的後台程序可能因SIGHUP
信號而死。分離腳本、後台程序和子shell
使用
nohup
,您也許可以擺脫這個小小的不便。#!/bin/sh read -s -p "Enter Password: " pw user=testuser share=/fshare cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share" nohup $cmd &
替代
disown
方案如果您可以從 切換
/bin/sh
到/bin/bash
,您也可以嘗試一下disown
。要了解更多資訊,只需輸入help disown
一個bash
實例。disown -h $cmd &
“很好地”殺死後台程序
現在,當談到終止你的程序時,你可以完美
Ctrl
地C
使用kill
. 只是不要發送殘酷的SIGKILL
. 相反,您可以使用:$ kill -2 [PID] $ kill -15 [PID]
這將向您的流程發送一個不錯的
SIGINT
(2) 或SIGTERM
(15)。您可能還想在啟動程序後列印 PID 值:... nohup $cmd & echo $!
…甚至更好,讓腳本等待 a
SIGINT
,然後將其發送回後台程序*(儘管這將使您的腳本保持在前台)*:#!/bin/sh read -s -p "Enter Password: " pw user=testuser share=/fshare cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share" nohup $cmd & # Storing the background process' PID. bg_pid=$! # Trapping SIGINTs so we can send them back to $bg_pid. trap "kill -2 $bg_pid" 2 # In the meantime, wait for $bg_pid to end. wait $bg_pid
如果 a
SIGINT
還不夠,只需使用 aSIGTERM
代替 (15) :trap "kill -15 $bg_pid" 2 15
這樣,當您的腳本接收到後台程序的
SIGINT
(Ctrl
+C
,kill -2
) 或SIGTERM
while 時wait
,它只會將信號中繼給它。如果這些信號確實殺死了sfk
實例,那麼wait
呼叫將返回,因此也會終止您的腳本 :)