
我正在將現有的 /etc/init.d 服務轉換為 systemd。它似乎有效,但我遇到了一個奇怪的問題。 systemd 服務將愉快地以命令“systemctl start service_name”啟動,並以“systemctl stop service_name”停止,但它似乎並沒有完全停止。底層應用程式檢查它是否已經在運行,如果是,則立即終止。這就是正在發生的事情。
以下是舊 /etc/init.d 腳本中的等效片段:
kill_process() {
pkill -SIGINT service_name
sleep 1
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGTERM service_name
sleep 1
fi
if [ -n "$(pgrep service_name)" ]; then
pkill -SIGKILL service_name
sleep 1
fi
if [ -z "$(pgrep service_name)" ]; then
rm -f /var/lock/subsys/service_name
fi
}
start() {
action $"Starting Service: " /sbin/service_name
}
stop() {
action $"Stopping Service: " kill_process
}
restart() {
stop
start
}
這是我對 systemd 等價物的初步嘗試:
[Unit]
Description=Service Name
[Service]
ExecStart=/sbin/service_name
[Install]
WantedBy=multi-user.target
我的理解是 systemd 服務將使用 SIGTERM 處理進程終止,但我已經嘗試了 KillSignal 和 ExecStop 的其他值。然而,我還沒有理解終止行為的這種差異。此外,如果我使用 SIGINT 手動終止應用程序,它也不會徹底終止服務。我想知道 /etc/init.d 是否在幕後做其他事情。
任何建議表示讚賞。
答案1
我只是想在這篇文章下方畫一條線,以防其他人有興趣。
如果 getppid() 尚未為 1(即尚未分叉),則作為服務一部分執行的 C 應用程式之前會使用 fork()。看起來,當應用程式由systemd 運行時,它的父PID 已經為1。 。我新增了一個特定的 SIGTERM 處理程序,該服務現在的行為符合預期。