CentOS 6.9下通过init.d运行PHP脚本异常问题咨询
Hey there, let's work through the two issues you're hitting with running a PHP script via an init.d service on CentOS 6.9. I've run into these exact problems before, so here's a step-by-step fix for each one:
This happens because your PHP script is still attached to the terminal session. When you close the terminal, it sends a SIGHUP signal that kills the process. To fix this, you need to run the script as a daemon (background process detached from the terminal).
Here are two reliable ways to do this in your init.d script:
- Use
nohupto ignore the SIGHUP signal, redirect output to a log file, and send the process to the background:
Thenohup php /path/to/your/script.php > /var/log/your_script.log 2>&1 &2>&1part redirects error output to the same log file as standard output, so you can debug issues later. - Alternatively, use
setsidto create a new session for the process, completely detaching it from your terminal:setsid php /path/to/your/script.php > /var/log/your_script.log 2>&1
This is because your init.d script isn't tracking the process ID (PID) of the running PHP script. By default, init.d thinks the service stops when the foreground command finishes—but since we're running PHP in the background, the script exits immediately, leading to a "stopped" status.
To fix this, you need to add PID file management to your init.d script:
Step 1: Define the PID file path
At the top of your init.d script, add a line to specify where the PID file will live:
PIDFILE="/var/run/your_script.pid"
Make sure the directory /var/run/ is writable by the user running the PHP script.
Step 2: Update the start function
When starting the script, write the process's PID to the file:
start() { echo -n "Starting your PHP script: " # Run the script in the background and save its PID nohup php /path/to/your/script.php > /var/log/your_script.log 2>&1 & echo $! > $PIDFILE echo "done" }
The $! variable holds the PID of the last background process.
Step 3: Add a stop function to kill the process using the PID
stop() { echo -n "Stopping your PHP script: " if [ -f $PIDFILE ]; then # Kill the process using the PID from the file kill $(cat $PIDFILE) # Clean up the PID file rm -f $PIDFILE echo "done" else echo "not running" fi }
Step 4: Add a status function to check if the process is active
status() { if [ -f $PIDFILE ]; then PID=$(cat $PIDFILE) # Check if the PID corresponds to a running process if ps -p $PID > /dev/null; then echo "PHP script is running with PID $PID" else echo "PID file exists but process is not running" # Clean up stale PID file rm -f $PIDFILE fi else echo "PHP script is not running" fi }
Step 5: Update the case statement to handle the status command
Make sure your script's main case block includes the status option:
case "$1" in start) start ;; stop) stop ;; status) status ;; restart) stop start ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 1 ;; esac
- Don't forget to make your init.d script executable:
chmod +x /etc/init.d/your_script_name - If you want the service to start on boot, register it with chkconfig:
chkconfig --add your_script_name chkconfig your_script_name on - Double-check permissions on your log file to ensure the PHP process can write to it:
(Replacechown your_script_user:your_script_group /var/log/your_script.logyour_script_userandyour_script_groupwith the actual user/group running your PHP script—oftenapacheorwww-data.)
内容的提问来源于stack exchange,提问作者Som

