如何写进程自动重启脚本

wen 实用脚本 27

本文目录导读:

如何写进程自动重启脚本

  1. Linux Shell 脚本(最常用)
  2. Systemd 服务(推荐用于系统服务)
  3. Python 脚本(跨平台)
  4. crontab 方式(简单有效)
  5. Docker 方式
  6. 使用建议

Linux Shell 脚本(最常用)

基础版本

#!/bin/bash
# 需要监控的进程名
PROCESS_NAME="your_process_name"
# 进程启动命令
START_CMD="/path/to/your/program"
while true; do
    # 检查进程是否存在
    if ! pgrep -x "$PROCESS_NAME" > /dev/null; then
        echo "$(date): Process $PROCESS_NAME not running, restarting..."
        # 启动进程
        $START_CMD &
        echo "$(date): Process restarted"
    fi
    # 每5秒检查一次
    sleep 5
done

增强版本(带日志和重试限制)

#!/bin/bash
PROCESS_NAME="your_process"
START_CMD="/path/to/your/program"
LOG_FILE="/var/log/process_monitor.log"
MAX_RETRIES=5
RETRY_COUNT=0
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
while true; do
    if ! pgrep -x "$PROCESS_NAME" > /dev/null; then
        if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then
            log "ERROR: Max retries ($MAX_RETRIES) reached. Exiting."
            exit 1
        fi
        log "Process not running, restart attempt $((RETRY_COUNT + 1))"
        $START_CMD &
        # 等待进程启动
        sleep 2
        if pgrep -x "$PROCESS_NAME" > /dev/null; then
            RETRY_COUNT=0
            log "Process restarted successfully"
        else
            RETRY_COUNT=$((RETRY_COUNT + 1))
            log "Failed to restart process"
        fi
    fi
    sleep 5
done

Systemd 服务(推荐用于系统服务)

创建服务文件 /etc/systemd/system/myapp.service

[Unit]
Description=My Application Service
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/app
ExecStart=/path/to/your/program
Restart=always
RestartSec=10
StartLimitInterval=300
StartLimitBurst=5
[Install]
WantedBy=multi-user.target

使用:

# 启动服务
sudo systemctl start myapp
# 设置开机自启
sudo systemctl enable myapp
# 查看状态
sudo systemctl status myapp
# 重新加载配置
sudo systemctl daemon-reload

Python 脚本(跨平台)

#!/usr/bin/env python3
import subprocess
import time
import logging
import os
import sys
class ProcessMonitor:
    def __init__(self, process_name, start_cmd, check_interval=5):
        self.process_name = process_name
        self.start_cmd = start_cmd
        self.check_interval = check_interval
        self.process = None
        # 配置日志
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('/var/log/process_monitor.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    def is_process_running(self):
        """检查进程是否在运行"""
        try:
            if self.process and self.process.poll() is None:
                return True
            return False
        except:
            return False
    def start_process(self):
        """启动进程"""
        try:
            self.logger.info(f"Starting process: {self.start_cmd}")
            self.process = subprocess.Popen(
                self.start_cmd.split(),
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            self.logger.info(f"Process started with PID: {self.process.pid}")
            return True
        except Exception as e:
            self.logger.error(f"Failed to start process: {e}")
            return False
    def run(self):
        """主循环"""
        self.logger.info(f"Starting monitor for process: {self.process_name}")
        while True:
            try:
                if not self.is_process_running():
                    self.logger.warning(f"Process {self.process_name} not running")
                    self.start_process()
                else:
                    self.logger.debug(f"Process {self.process_name} is running")
                time.sleep(self.check_interval)
            except KeyboardInterrupt:
                self.logger.info("Monitor stopped by user")
                if self.process:
                    self.process.terminate()
                sys.exit(0)
            except Exception as e:
                self.logger.error(f"Monitor error: {e}")
                time.sleep(self.check_interval)
if __name__ == "__main__":
    monitor = ProcessMonitor(
        process_name="myapp",
        start_cmd="/path/to/your/program --args",
        check_interval=5
    )
    monitor.run()

crontab 方式(简单有效)

#!/bin/bash
# 保存为 /usr/local/bin/check_process.sh
PROCESS="your_process_name"
START_CMD="/path/to/your/program"
if ! pgrep -x "$PROCESS" > /dev/null; then
    echo "$(date): Starting $PROCESS"
    $START_CMD &
fi

添加到 crontab:

# 每分钟检查一次
* * * * * /usr/local/bin/check_process.sh

Docker 方式

Docker Compose 文件 docker-compose.yml

version: '3'
services:
  myapp:
    image: your_image:latest
    restart: always
    restart_policy:
      condition: on-failure
      max_attempts: 3
    healthcheck:
      test: ["CMD", "pgrep", "-f", "your_process"]
      interval: 30s
      timeout: 10s
      retries: 3

使用建议

  1. 选择合适的方式

    • 系统服务:使用 systemd
    • 临时监控:使用 shell 脚本
    • 复杂逻辑:使用 Python
    • Docker 环境:使用 Docker 重启策略
  2. 注意事项

    • 设置合理的检查间隔(不要太频繁)
    • 添加日志记录方便排查问题
    • 设置重启次数限制避免无限重启
    • 考虑优雅停止和资源清理
  3. 生产环境建议

    • 使用 supervisor 或 systemd 等专业工具
    • 配置监控告警系统
    • 添加健康检查机制

需要我详细解释某个特定场景的实现吗?

抱歉,评论功能暂时关闭!