如何正確停止busybox shell程序和子程序?
實際的伺服器程序由 shell 腳本生成
我正在嘗試在執行busybox 1.24(ash shell)的路由器上的Entware中為djb daemontools編寫一個初始化腳本。daemontools 啟動自身的方式是使用svscanboot shell 腳本。請注意,我已從svscanboot中刪除了 readproctitle。
PATH=/opt/sbin:/opt/bin:/bin:/sbin:/usr/bin:/usr/sbin exec </dev/null exec >/dev/null exec 2>/dev/null /opt/bin/svc -dx /opt/service/* /opt/service/*/log env - PATH=$PATH svscan /opt/service 2>&1
父 shell 腳本程序產生一個(後代)
svscan
子程序,它是實際執行的伺服器程序。shell程序接收到TERM信號
執行
svscanboot &
(在後台)並殺死父程序會導致子程序執行:# ps l | grep svscan S 0 1526 1 1560 404 0:0 22:57 00:00:00 {svscanboot} /bin/sh /opt/bin/svscanboot S 0 1528 1526 976 252 0:0 22:57 00:00:00 svscan /opt/service # killall svscanboot
但是 svscan 會繼續執行
# ps l | grep svscan S 0 1528 1 976 252 0:0 22:57 00:00:00 svscan /opt/service
執行
svscanboot
(在前台)並殺死父程序也會導致子程序仍在執行:# ps l | grep svscan S 0 676 671 1560 400 pts1 23:41 00:00:00 {svscanboot} /bin/sh /opt/bin/svscanboot S 0 678 676 976 252 pts1 23:41 00:00:00 svscan /opt/service # killall svscanboot # ps l | grep svscan S 0 678 1 976 252 pts1 23:41 00:00:00 svscan /opt/service
Busybox 非常有限,
killall
只有標誌-l
,-q
並且ps
只有w
ide、l
ong 和 showT
執行緒。
Ctrl
並且當使用+退出前台版本時,C
父程序和子程序都會終止。在這種情況下如何停止父程序和子程序,最好使用
killall
並最終通過修改svscanboot
?
執行
在我閱讀了“exec env COMMAND”的含義的問題和答案之後,一個可能的解決方案可能是在前面
env …
加上exec
. 這將防止產生子程序。然而ps
輸出{svscanboot} /bin/sh /opt/bin/svscanboot
。svscan /opt/service
該名稱將更改為exec
.或擷取信號
處理此問題的另一種方法是通過將信號傳播到子程序的陷阱。就像在 Bash 中將 SIGTERM 轉發給孩子或更詳細地解釋了http://veithen.github.io/2014/11/16/sigterm-propagation.html 此解決方案路線的問題是
-9
不能擷取SIGKILL aka 信號編號.執行名稱更改解決方法
由於無法擷取 KILL 信號,我將選擇
exec
路由:… exec env - PATH=$PATH svscan /opt/service 2>&1
由於名稱已更改,這仍然會使在 Entware 初始化系統中停止/殺死/重新配置“svscanboot”變得複雜。該 exec 程序名稱更改將需要解決方法。
模仿 svscanboot
entware-daemontools-init-script 可以更改為模仿
svscanboot
,例如:ENABLED=yes #PRECMD="exec </dev/null;exec >/dev/null;exec 2>/dev/null;/opt/bin/svc -dx /opt/service/* /opt/service/*/log" PROCS="svscan" ARGS="/opt/service 2>&1" PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin PREARGS="env - PATH=$PATH" DESC="daemontools"
註釋的 PRECMD 使得它
svscan
不會啟動。