You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Systemd兼容SysV init.d脚本:启动正常但停止失效求助

Troubleshooting Your Init Script's Non-Working Stop Function

Hey there! Let's figure out why your stop command isn't doing what it's supposed to. Looking at the snippet you shared, the issue is pretty straightforward—your stop case only logs a failure message, but doesn't actually include any logic to terminate your service's process. Let's fix that step by step.

The Core Problem

Right now, when you run service test stop, your script just prints "Stop!" but doesn't send any signals to the running test process or clean up associated files (like PID files). Systemd or the init system can't guess how to stop your service—you have to tell it explicitly.

Fixing the Stop Logic

Here's how to update your script with proper stop functionality, using standard LSB tools that play nice with Systemd:

First, make sure you're using start-stop-daemon (it's part of the lsb-base package you already depend on) to safely manage your process. This tool handles PID files, signal retries, and process cleanup reliably.

Updated Script Snippet

#!/bin/sh
# ### BEGIN INIT INFO
# Provides: test
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Test.
# Description: Test.
# ### END INIT INFO

# Define LSB log_* functions.
. /lib/lsb/init-functions

# Path to your service executable
SERVICE_EXEC="/path/to/your/test/service"
# PID file location (most services write this automatically, or you can set it)
PID_FILE="/var/run/test.pid"

case "$1" in
    start)
        log_daemon_msg "Starting test service" "test"
        # Start the service in background, create PID file
        start-stop-daemon --start --background --make-pidfile --pidfile $PID_FILE --exec $SERVICE_EXEC
        log_end_msg $?
        ;;
    stop)
        log_daemon_msg "Stopping test service" "test"
        # Check if PID file exists first
        if [ -f $PID_FILE ]; then
            # Send TERM signal (graceful shutdown), wait 30s, then send KILL if needed
            start-stop-daemon --stop --pidfile $PID_FILE --retry TERM/30/KILL/5
            # Clean up the PID file after process stops
            rm -f $PID_FILE
            log_end_msg $?
        else
            log_warning_msg "Test service isn't running (no PID file found)"
            log_end_msg 1
        fi
        ;;
    status)
        # Optional: Add status check logic
        status_of_proc -p $PID_FILE $SERVICE_EXEC "test" && exit 0 || exit $?
        ;;
    restart|force-reload)
        $0 stop
        sleep 1
        $0 start
        ;;
    *)
        echo "Usage: $0 {start|stop|status|restart|force-reload}"
        exit 2
        ;;
esac

Key Changes Explained

  • Added variables for your service executable and PID file to keep the script clean.
  • In the stop case:
    • Checks if the PID file exists to avoid errors when the service isn't running.
    • Uses start-stop-daemon to send a TERM signal first (for graceful shutdown), waits 30 seconds, and sends a KILL signal if the process won't exit.
    • Cleans up the PID file once the process is stopped.
  • Added optional status and restart cases for better service management.

Bonus: Consider a Systemd Unit File (Better Compatibility)

Since you're targeting Systemd, writing a native .service file is often simpler and more reliable than a traditional init script. Here's an example:

[Unit]
Description=Test Service
After=remote-fs.target syslog.target

[Service]
ExecStart=/path/to/your/test/service
PIDFile=/var/run/test.pid
Restart=on-failure  # Optional: Auto-restart if service crashes

[Install]
WantedBy=multi-user.target

To use this:

  1. Save it as /etc/systemd/system/test.service
  2. Run sudo systemctl daemon-reload to load the new unit
  3. Enable it on boot with sudo systemctl enable test
  4. Start/stop it with sudo systemctl start test or sudo systemctl stop test

Systemd handles all the stop logic automatically here, so you don't have to write any process termination code yourself.

Final Checks

  • Make sure your script has execute permissions: sudo chmod +x /etc/init.d/test
  • If you stick with the init script, update the SERVICE_EXEC and PID_FILE paths to match your actual service.

内容的提问来源于stack exchange,提问作者Crankycyclops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:17:12