实现Python脚本报错自动重执行(Zabbix+树莓派GPIO监控场景)
Got it, let's make sure your Zabbix monitoring script stays up and running even when it hits errors. Here are three practical approaches, ordered by reliability:
1. Systemd Service (Recommended for Production)
Systemd is the built-in service manager on most modern Linux distros (including Raspberry Pi OS), and it’s the most robust way to keep your script alive. Here’s how to set it up:
Step 1: Create a Systemd Service File
Create a new file at /etc/systemd/system/raspi-ac-monitor.service with the following content (replace paths with your actual script location):
[Unit] Description=Raspberry Pi AC Loss Monitor for Zabbix After=network.target # Wait for network before starting (since Zabbix needs it) [Service] ExecStart=/usr/bin/python3 /home/pi/raspi.py # Path to your script Restart=always # Restart the service no matter why it exits RestartSec=5 # Wait 5 seconds before restarting User=pi # Run as the pi user (adjust if needed) WorkingDirectory=/home/pi/ # Directory where your script lives StandardOutput=journal+console # Log output to system journal and console StandardError=journal+console [Install] WantedBy=multi-user.target # Start when the system reaches multi-user mode
Step 2: Enable and Start the Service
Run these commands to activate the service:
sudo systemctl daemon-reload # Let systemd detect the new service sudo systemctl start raspi-ac-monitor.service # Start the service now sudo systemctl enable raspi-ac-monitor.service # Set it to start on boot
Bonus: Check Logs
If you need to debug issues, view the service logs with:
journalctl -u raspi-ac-monitor.service -f # -f follows live logs
2. Add Error Handling Directly in the Python Script
If you prefer keeping everything within Python, wrap your core logic in a try/except block and restart the script when errors occur. Here’s the modified version of your script:
import RPi.GPIO as GPIO import time from pyzabbix import ZabbixSender, ZabbixMetric import sys import os def run_monitoring(): while True: try: GPIO.setmode(GPIO.BCM) GPIO.setup(22, GPIO.IN) value = GPIO.input(22) # Send data to Zabbix packet = [ZabbixMetric('raspi', 'acloss', value)] sender = ZabbixSender(use_config=True) sender.send(packet) print(f"AC OK - Value: {value}") GPIO.cleanup() time.sleep(5) except Exception as e: print(f"Error occurred: {str(e)}. Restarting script...") GPIO.cleanup() # Clean up GPIO pins to avoid conflicts time.sleep(2) # Restart the current script os.execv(sys.executable, ['python3'] + sys.argv) if __name__ == "__main__": run_monitoring()
This will catch any unexpected errors, clean up GPIO resources, and restart the script automatically.
3. Simple Shell Script Wrapper
A quick-and-dirty option is to use a shell script to keep restarting your Python script if it exits. Create a file named monitor_wrapper.sh:
#!/bin/bash SCRIPT_PATH="/home/pi/raspi.py" # Replace with your script path while true; do echo "Starting monitoring script..." python3 "$SCRIPT_PATH" EXIT_CODE=$? echo "Script exited with code $EXIT_CODE. Restarting in 5 seconds..." sleep 5 done
Make the script executable:
chmod +x monitor_wrapper.sh
Run it in the background (and keep it running after you log out):
nohup ./monitor_wrapper.sh &
Note: This is less reliable than systemd because if the shell script itself crashes, your monitoring stops. Also, logging is more basic compared to systemd’s journal.
内容的提问来源于stack exchange,提问作者Vincenzo Denicolo

