本文目录导读:

Linux/Unix 系统 - Shell 脚本
基础后台运行方式
#!/bin/bash
# sync_task.sh
while true; do
# 你的同步任务
rsync -avz /source/path/ /destination/path/
# 等待间隔(示例:每5分钟执行一次)
sleep 300
done
运行方式
# 后台运行 nohup ./sync_task.sh > sync.log 2>&1 & # 或使用 & ./sync_task.sh &
使用 nohup + 日志管理
#!/bin/bash
# sync_task_with_logs.sh
LOG_FILE="/var/log/sync_$(date +%Y%m%d).log"
sync_files() {
echo "[$(date)] Starting sync..." >> $LOG_FILE
# 执行同步命令
rsync -avz --delete /source/ /destination/ 2>&1 | tee -a $LOG_FILE
# 或使用其他同步工具
# scp -r /source/* user@remote:/destination/
# rclone sync /source remote:destination
echo "[$(date)] Sync completed" >> $LOG_FILE
}
# 主循环
while true; do
sync_files
# 检查是否有停止标志文件
if [ -f "/tmp/stop_sync" ]; then
echo "Stop signal received. Exiting..." >> $LOG_FILE
exit 0
fi
sleep 300 # 5分钟间隔
done
Python 脚本方案
#!/usr/bin/env python3
# sync_daemon.py
import os
import time
import logging
import subprocess
import signal
import sys
class SyncDaemon:
def __init__(self, source, destination, interval=300):
self.source = source
self.destination = destination
self.interval = interval
self.running = True
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/sync_daemon.log'),
logging.StreamHandler()
]
)
def sync(self):
"""执行同步任务"""
try:
# rsync 示例
cmd = f"rsync -avz --delete {self.source} {self.destination}"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
logging.info("Sync completed successfully")
if result.stdout:
logging.debug(result.stdout)
else:
logging.error(f"Sync failed: {result.stderr}")
except Exception as e:
logging.error(f"Sync error: {e}")
def stop(self, signum, frame):
"""停止服务"""
logging.info("Stopping sync daemon...")
self.running = False
def run(self):
"""主循环"""
# 注册信号处理
signal.signal(signal.SIGTERM, self.stop)
signal.signal(signal.SIGINT, self.stop)
logging.info(f"Starting sync daemon between {self.source} and {self.destination}")
logging.info(f"Interval: {self.interval} seconds")
while self.running:
self.sync()
# 等待指定间隔,但每秒检查是否应该停止
for _ in range(self.interval):
if not self.running:
break
time.sleep(1)
logging.info("Sync daemon stopped")
if __name__ == "__main__":
# 使用示例
daemon = SyncDaemon(
source="/data/source/",
destination="/data/destination/",
interval=300 # 5分钟
)
daemon.run()
使用 systemd 管理(推荐)
创建 service 文件
# /etc/systemd/system/sync-daemon.service [Unit] Description=File Sync Daemon After=network.target [Service] Type=simple User=your_user ExecStart=/usr/local/bin/sync_daemon.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
使用方法
# 创建软链接 sudo ln -s /path/to/sync_daemon.service /etc/systemd/system/ # 重新加载 systemd sudo systemctl daemon-reload # 启动服务 sudo systemctl start sync-daemon # 设置开机自启 sudo systemctl enable sync-daemon # 查看状态 sudo systemctl status sync-daemon # 查看日志 sudo journalctl -u sync-daemon -f
Docker 化运行
Dockerfile
FROM alpine:latest # 安装必要工具 RUN apk add --no-cache rsync openssh # 创建同步脚本 COPY sync_script.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/sync_script.sh # 启动脚本 CMD ["/usr/local/bin/sync_script.sh"]
运行
# 后台运行容器 docker run -d \ --name sync-daemon \ -v /host/source:/source:ro \ -v /host/destination:/destination \ your-sync-image
生产环境的最佳实践
综合脚本示例
#!/bin/bash
# 配置文件
CONFIG_FILE="/etc/sync-daemon.conf"
PID_FILE="/var/run/sync-daemon.pid"
LOG_FILE="/var/log/sync-daemon.log"
ERROR_LOG="/var/log/sync-daemon-error.log"
# 读取配置
source $CONFIG_FILE
# 函数:记录日志
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}
# 函数:记录错误
error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> $ERROR_LOG
}
# 函数:执行同步
do_sync() {
if rsync -avz --delete \
--log-file=$LOG_FILE \
--exclude-from=$EXCLUDE_FILE \
$SOURCE $DESTINATION; then
log "Sync completed successfully"
return 0
else
error "Sync failed with exit code $?"
return 1
fi
}
# 主程序
case "$1" in
start)
# 检查是否已在运行
if [ -f $PID_FILE ]; then
echo "Already running (PID: $(cat $PID_FILE))"
exit 1
fi
# 后台执行
(
echo $$ > $PID_FILE
log "Sync daemon started"
while true; do
do_sync
# 发送心跳
if [ $((SECONDS % 3600)) -eq 0 ]; then
log "Heartbeat - Service alive"
fi
sleep $INTERVAL
done
) &
echo "Started (PID: $!)"
;;
stop)
if [ -f $PID_FILE ]; then
kill $(cat $PID_FILE) 2>/dev/null
rm -f $PID_FILE
log "Sync daemon stopped"
echo "Stopped"
else
echo "Not running"
fi
;;
status)
if [ -f $PID_FILE ] && kill -0 $(cat $PID_FILE) 2>/dev/null; then
echo "Running (PID: $(cat $PID_FILE))"
else
echo "Not running"
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
exit 1
;;
esac
监控和告警
# monitor_sync.py
import subprocess
import smtplib
from email.mime.text import MIMEText
import time
def check_sync():
# 检查同步状态
result = subprocess.run(
"systemctl status sync-daemon",
shell=True,
capture_output=True,
text=True
)
# 检查最近同步时间
last_sync = subprocess.run(
"stat -c %Y /var/log/sync-daemon.log",
shell=True,
capture_output=True,
text=True
)
current_time = time.time()
if last_sync.stdout:
last_sync_time = float(last_sync.stdout.strip())
if current_time - last_sync_time > 600: # 10分钟没有同步
send_alert(f"Sync hasn't run for 10 minutes")
- 简单场景:使用
nohup+ shell 脚本 - 生产环境:使用
systemd服务 - 需要灵活性:使用 Python 脚本
- 容器化部署:使用 Docker
- 关键考虑:
- 错误处理和重试机制
- 日志记录
- 资源限制
- 监控告警
- 优雅关闭
选择哪种方案取决于你的具体需求和环境。