本文目录导读:

- 使用 rsync(适用于 Linux/Mac)
- 使用 unison(专门的双向同步工具)
- 使用 rclone(支持云存储)
- 定时执行方案(crontab)
- inotify 实时监控(Linux)
- 完整的生产级脚本
- 注意事项:
- 推荐方案:
要实现本地与远程文件的双向同步,有几种成熟的方法,我来帮你梳理一下:
使用 rsync(适用于 Linux/Mac)
这是最常用的方法,但需要两次传输:
#!/bin/bash # 双向同步脚本 LOCAL_DIR="/path/to/local/" REMOTE_DIR="user@host:/path/to/remote/" # 本地到远程 rsync -avz --delete "$LOCAL_DIR" "$REMOTE_DIR" # 远程到本地 rsync -avz --delete "$REMOTE_DIR" "$LOCAL_DIR"
优化版本(避免循环触发):
#!/bin/bash
LOCAL_DIR="/path/to/local/"
REMOTE_DIR="user@host:/path/to/remote/"
# 创建临时锁文件防止冲突
LOCK_FILE="/tmp/sync.lock"
if [ -f "$LOCK_FILE" ]; then
exit 1
fi
touch "$LOCK_FILE"
# 同步方向标记(防止双向同时修改同一文件产生冲突)
rsync -avz --update --delete "$LOCAL_DIR" "$REMOTE_DIR"
rsync -avz --update --delete "$REMOTE_DIR" "$LOCAL_DIR"
rm -f "$LOCK_FILE"
使用 unison(专门的双向同步工具)
安装:sudo apt-get install unison 或 brew install unison
#!/bin/bash
# unison 双向同步配置
LOCAL_DIR="/path/to/local"
REMOTE_DIR="ssh://user@host//path/to/remote"
unison "$LOCAL_DIR" "$REMOTE_DIR" \
-batch \
-auto \
-times \
-perms 0 \
-ignore "Name .git" \
-ignore "Name *.tmp"
使用 rclone(支持云存储)
安装:sudo apt install rclone
#!/bin/bash
# rclone 双向同步
LOCAL_DIR="/path/to/local"
REMOTE_DIR="remote:path/to/remote"
# --backup-dir 参数备份冲突文件
rclone bisync "$LOCAL_DIR" "$REMOTE_DIR" \
--verbose \
--create-empty-dirs \
--compare-size \
--resync
定时执行方案(crontab)
# 每5分钟同步一次
*/5 * * * * /path/to/sync_script.sh
# 或者在后台循环执行
while true; do
/path/to/sync_script.sh
sleep 300 # 5分钟
done
inotify 实时监控(Linux)
#!/bin/bash
# 基于 inotify 的实时同步
LOCAL_DIR="/path/to/local"
REMOTE_DIR="user@host:/path/to/remote"
inotifywait -m -r -e modify,create,delete,move "$LOCAL_DIR" |
while read path action file; do
# 延迟一点防止频繁同步
sleep 2
rsync -avz --delete "$LOCAL_DIR" "$REMOTE_DIR"
done
完整的生产级脚本
#!/bin/bash
# 配置
LOCAL_DIR="/path/to/local"
REMOTE_USER="username"
REMOTE_HOST="remote.server.com"
REMOTE_DIR="/path/to/remote"
SSH_KEY="/path/to/ssh/key"
LOG_FILE="/var/log/rsync_sync.log"
# 函数:日志记录
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 函数:执行同步
sync_direction() {
local source="$1"
local dest="$2"
local direction="$3"
rsync -avz \
--delete \
--update \
--exclude='*.tmp' \
--exclude='.DS_Store' \
--exclude='node_modules' \
--progress \
--log-file="$LOG_FILE" \
-e "ssh -i $SSH_KEY" \
"$source" "$dest"
if [ $? -eq 0 ]; then
log "成功: $direction 同步完成"
else
log "错误: $direction 同步失败"
fi
}
# 主同步逻辑
main() {
log "开始双向同步..."
# 本地 -> 远程
sync_direction "$LOCAL_DIR" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}" "本地到远程"
# 远程 -> 本地
sync_direction "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}" "$LOCAL_DIR" "远程到本地"
log "双向同步完成"
}
# 执行
main "$@"
注意事项:
- 冲突处理:双向同步最大问题是文件冲突,建议使用
--update参数,保留最新版本 - 排除项:排除缓存、临时文件、日志等
- SSH免密码:配置 SSH 密钥认证
- 增量同步:使用
--update或--checksum只同步变更内容 - 备份:建议同步前做增量备份,防止数据丢失
推荐方案:
- 简单场景:rsync 两遍同步
- 需要冲突处理:unison
- 跨平台:rclone
- 实时同步:inotify + rsync
- 大型项目:考虑使用 Syncthing(开源P2P同步工具)
选择什么方案取决于你的具体需求:数据量、同步频率、冲突处理方式等,如果有更具体的使用场景,我可以提供更针对性的建议。