Shell脚本如何同步文件到远程服务器

wen 实用脚本 1

本文目录导读:

Shell脚本如何同步文件到远程服务器

  1. 复制公钥到远程服务器
  2. 添加定时任务(每小时同步一次)

使用 rsync 同步(推荐)

基本同步脚本

#!/bin/bash
# 配置变量
LOCAL_DIR="/path/to/local/directory/"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
# 执行同步
rsync -avz --delete $LOCAL_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}

带日志和错误处理的同步脚本

#!/bin/bash
# 配置变量
LOCAL_DIR="/path/to/local/directory/"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
LOG_FILE="/var/log/sync.log"
SSH_KEY="/path/to/ssh/private/key"
# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 检查必要配置
if [ ! -d "$LOCAL_DIR" ]; then
    log "错误: 本地目录 $LOCAL_DIR 不存在"
    exit 1
fi
# 执行同步
log "开始同步文件..."
rsync -avz --delete \
    -e "ssh -i $SSH_KEY" \
    --log-file=$LOG_FILE \
    --progress \
    $LOCAL_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}
# 检查同步结果
if [ $? -eq 0 ]; then
    log "同步成功完成"
else
    log "同步失败!"
    exit 1
fi

使用 scp 同步

基本 scp 同步

#!/bin/bash
LOCAL_FILE="/path/to/local/file.txt"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
# 同步单个文件
scp $LOCAL_FILE ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}

同步整个目录

#!/bin/bash
LOCAL_DIR="/path/to/local/directory"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
# 递归同步目录
scp -r $LOCAL_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}

带排除规则的同步脚本

#!/bin/bash
# 配置
LOCAL_DIR="/path/to/local/directory/"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
EXCLUDE_FILE="/path/to/exclude.txt"
# exclude.txt 内容示例:
# *.log
# .git/
# node_modules/
# temp/
# 执行同步,排除不需要的文件
rsync -avz --delete \
    --exclude-from=$EXCLUDE_FILE \
    --progress \
    $LOCAL_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}
if [ $? -eq 0 ]; then
    echo "同步成功完成"
else
    echo "同步失败"
    exit 1
fi

实时监控并同步(使用 inotify)

#!/bin/bash
WATCH_DIR="/path/to/watch/directory"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote/directory/"
# 监控文件变化并自动同步
inotifywait -m -r -e modify,create,delete,move $WATCH_DIR | while read path action file; do
    echo "检测到文件变化: $file - $action"
    rsync -avz --delete $WATCH_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}
done

带 SSH 密钥配置的完整脚本

#!/bin/bash
# ====== 配置文件 [config.sh] ======
# LOCAL_DIR="/path/to/local/directory/"
# REMOTE_USER="username"
# REMOTE_HOST="remote.server.com"
# REMOTE_DIR="/path/to/remote/directory/"
# SSH_KEY="/path/to/ssh/private/key"
# MAX_RETRIES=3
# LOG_FILE="/var/log/rsync-sync.log"
# ====== 主脚本 [sync.sh] ======
#!/bin/bash
# 加载配置
source ./config.sh
# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# 错误处理函数
handle_error() {
    local retry_count=$1
    if [ $retry_count -lt $MAX_RETRIES ]; then
        log "重试 #$((retry_count + 1))..."
        sleep 5
        return 1
    else
        log "达到最大重试次数 $MAX_RETRIES,同步失败"
        exit 1
    fi
}
# 检查 SSH 连接
check_ssh_connection() {
    ssh -i $SSH_KEY -q ${REMOTE_USER}@${REMOTE_HOST} exit
    if [ $? -ne 0 ]; then
        log "无法连接到远程服务器 $REMOTE_HOST"
        return 1
    fi
    return 0
}
# 执行同步
sync_files() {
    local retry_count=0
    while [ $retry_count -lt $MAX_RETRIES ]; do
        log "尝试同步文件 (尝试 #$((retry_count + 1)))"
        rsync -avz --delete \
            -e "ssh -i $SSH_KEY" \
            --log-file=$LOG_FILE \
            --progress \
            --timeout=30 \
            $LOCAL_DIR ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}
        if [ $? -eq 0 ]; then
            log "同步成功完成"
            return 0
        else
            retry_count=$((retry_count + 1))
            handle_error $retry_count
        fi
    done
    return 1
}
# 主函数
main() {
    log "开始同步脚本"
    # 检查本地目录
    if [ ! -d "$LOCAL_DIR" ]; then
        log "错误: 本地目录 $LOCAL_DIR 不存在"
        exit 1
    fi
    # 检查 SSH 连接
    if ! check_ssh_connection; then
        exit 1
    fi
    # 执行同步
    if sync_files; then
        log "脚本执行完成"
    else
        log "脚本执行失败"
        exit 1
    fi
}
# 执行主函数
main

使用说明

  1. 设置 SSH 密钥认证(推荐):
    # 生成 SSH 密钥(如果没有)
    ssh-keygen -t rsa -b 4096

复制公钥到远程服务器

ssh-copy-id username@remote.server.com


2. **设置脚本执行权限**:
```bash
chmod +x sync.sh
  1. 设置定时任务(cron)
    # 编辑 crontab
    crontab -e

添加定时任务(每小时同步一次)

0 /path/to/sync.sh


## 注意事项
1. **安全性**:
   - 使用 SSH 密钥认证而非密码
   - 不要在脚本中硬编码密码
   - 限制脚本文件权限(chmod 700)
2. **性能考虑**:
   - rsync 比 scp 更高效,支持增量同步
   - 使用 `--compress` 或 `-z` 压缩传输
   - 合理使用排除规则减少传输量
3. **可靠性**:
   - 添加日志记录
   - 实现错误处理和重试机制
   - 检查网络连接状态
4. **排除文件**:
   - 临时文件 (*.tmp)
   - 日志文件 (*.log)
   - 版本控制目录 (.git, .svn)
   - 缓存目录 (node_modules, cache)
选择哪种方法取决于你的具体需求:rsync 适用于定期同步大量文件,scp 适合简单的一次性传输,inotify 适合实时同步场景。

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