跨服务器单向同步文件夹最佳实践

背景

在多服务器协作场景中,经常需要在服务器之间自动同步文件。传统的双向同步(如 syncthing)存在冲突风险,而单向同步(放入即同步,同步后删除源文件)更加简单可靠。

本文介绍如何在 Linux(Gateway)和 macOS(Mac mini)之间构建两个单向同步文件夹,实现:

  • Gateway → Mac mini:文件放入 /root/sync-outbox 自动同步到 Mac,同步后删除源文件
  • Mac mini → Gateway:文件放入 ~/sync-outbox 自动同步到 Gateway,同步后删除源文件

技术方案

核心工具

  • rsync:可靠的文件同步工具,支持增量传输
  • systemd timer:Linux 定时任务(替代 cron)
  • launchd:macOS 定时任务(替代 cron)
  • SSH 免密登录:自动同步的前提

同步流程

1
2
3
4
5
6
7
8
9
10
11
Gateway                        Mac mini
┌─────────────┐ ┌─────────────┐
sync-outbox │ ──rsync──> │ sync-inbox │
│ (源文件删除)│ │ │
└─────────────┘ └─────────────┘

Mac mini Gateway
┌─────────────┐ ┌─────────────┐
sync-outbox │ ──rsync──> │ sync-inbox │
│ (源文件删除)│ │ │
└─────────────┘ └─────────────┘

完整配置步骤

1. 准备 SSH 免密登录

在 Gateway 上生成密钥:

1
2
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_sync -N ""
ssh-copy-id -i ~/.ssh/id_rsa_sync.pub user@your-server-ip

测试连接:

1
ssh user@your-server-ip "echo '✅ SSH连接成功'"

2. 创建同步脚本

Gateway → Mac mini 同步脚本

创建 /root/.openclaw/workspace/sync-to-mac.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/bash
# Gateway → Mac mini 单向同步(同步后删除源文件)

MAC_HOST="user@your-server-ip"
GATEWAY_SYNC_DIR="/root/sync-outbox"
MAC_SYNC_DIR="/Users/username/sync-inbox"

echo "=========================================="
echo "📤 Gateway → Mac mini 单向同步"
echo "=========================================="

# 创建本地同步目录
mkdir -p "$GATEWAY_SYNC_DIR"

# 检查是否有文件需要同步
FILE_COUNT=$(find "$GATEWAY_SYNC_DIR" -type f | wc -l)
if [ "$FILE_COUNT" -eq 0 ]; then
echo "📭 没有文件需要同步"
exit 0
fi

echo "📦 发现 $FILE_COUNT 个文件,开始同步..."

# 在Mac mini创建目标目录
ssh "$MAC_HOST" "mkdir -p $MAC_SYNC_DIR"

# 同步文件(保留源文件,后续删除)
rsync -avz --remove-source-files \
"$GATEWAY_SYNC_DIR/" "$MAC_HOST:$MAC_SYNC_DIR/"

# 删除空目录
find "$GATEWAY_SYNC_DIR" -type d -empty -delete

echo "✅ 同步完成,源文件已删除"
echo "📊 同步统计:"
echo " - 已同步文件: $FILE_COUNT 个"
echo " - Mac mini位置: $MAC_SYNC_DIR"
echo "=========================================="

赋予执行权限:

1
2
chmod +x /root/.openclaw/workspace/sync-to-mac.sh
mkdir -p /root/sync-outbox /root/sync-inbox

Mac mini → Gateway 同步脚本

在 Mac mini 上创建 ~/sync-to-gateway.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# Mac mini → Gateway 单向同步(同步后删除源文件)

GATEWAY_HOST="root@your-gateway-ip"
MAC_SYNC_DIR="/Users/username/sync-outbox"
GATEWAY_SYNC_DIR="/root/sync-inbox"

echo "=========================================="
echo "📤 Mac mini → Gateway 单向同步"
echo "=========================================="

# 检查是否有文件需要同步
FILE_COUNT=$(find "$MAC_SYNC_DIR" -type f 2>/dev/null | wc -l)
if [ "$FILE_COUNT" -eq 0 ]; then
echo "📭 没有文件需要同步"
exit 0
fi

echo "📦 发现 $FILE_COUNT 个文件,开始同步..."

# 创建Gateway目标目录
ssh "$GATEWAY_HOST" "mkdir -p $GATEWAY_SYNC_DIR"

# 同步文件(保留源文件,后续删除)
rsync -avz --remove-source-files \
"$MAC_SYNC_DIR/" "$GATEWAY_HOST:$GATEWAY_SYNC_DIR/"

# 删除空目录
find "$MAC_SYNC_DIR" -type d -empty -delete 2>/dev/null

echo "✅ 同步完成,源文件已删除"
echo "📊 已同步: $FILE_COUNT 个文件"
echo "=========================================="

赋予执行权限:

1
2
chmod +x ~/sync-to-gateway.sh
mkdir -p ~/sync-outbox ~/sync-inbox

3. 配置自动同步

Linux(Gateway)使用 systemd timer

创建 systemd service 文件 /etc/systemd/system/sync-to-mac.service

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Auto sync files to Mac mini
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/.openclaw/workspace
ExecStart=/root/.openclaw/workspace/sync-to-mac.sh
Restart=no

[Install]
WantedBy=multi-user.target

创建 systemd timer 文件 /etc/systemd/system/sync-to-mac.timer

1
2
3
4
5
6
7
8
9
[Unit]
Description=Auto sync files to Mac mini every minute

[Timer]
OnCalendar=*:*:00
Persistent=true

[Install]
WantedBy=timers.target

启用定时任务:

1
2
3
systemctl daemon-reload
systemctl enable sync-to-mac.timer
systemctl start sync-to-mac.timer

查看状态:

1
2
systemctl status sync-to-mac.timer
systemctl list-timers | grep sync

macOS 使用 launchd

创建 launchd plist 文件 ~/Library/LaunchAgents/com.user.sync-to-gateway.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.sync-to-gateway</string>
<key>ProgramArguments</key>
<array>
<string>/Users/username/sync-to-gateway.sh</string>
</array>
<key>StartInterval</key>
<integer>60</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/sync-to-gateway.log</string>
<key>StandardErrorPath</key>
<string>/tmp/sync-to-gateway.log</string>
</dict>
</plist>

加载 LaunchAgent:

1
launchctl load ~/Library/LaunchAgents/com.user.sync-to-gateway.plist

查看状态:

1
launchctl list | grep sync-to-gateway

4. 使用方法

Gateway 发送文件到 Mac mini

1
2
3
4
5
# 放入文件
cp your-file.txt /root/sync-outbox/

# 1分钟内自动同步到 Mac mini 的 /Users/username/sync-inbox/
# 同步完成后,Gateway 上的文件自动删除

Mac mini 发送文件到 Gateway

1
2
3
4
5
# 放入文件
cp your-file.txt ~/sync-outbox/

# 1分钟内自动同步到 Gateway 的 /root/sync-inbox/
# 同步完成后,Mac mini 上的文件自动删除

5. 手动触发同步

1
2
3
4
5
# Gateway → Mac
/root/.openclaw/workspace/sync-to-mac.sh

# Mac → Gateway
~/sync-to-gateway.sh

6. 查看日志

Gateway 日志:

1
journalctl -u sync-to-mac.timer -f

Mac mini 日志:

1
tail -f /tmp/sync-to-gateway.log

rsync 参数说明

参数 说明
-a 归档模式,保留权限、时间戳等
-v 详细输出
-z 压缩传输
--remove-source-files 同步成功后删除源文件
--delete 删除目标目录中不存在于源目录的文件(谨慎使用)

常见问题

Q1: 如何修改同步频率?

Linux:
修改 /etc/systemd/system/sync-to-mac.timer

1
2
[Timer]
OnCalendar=*:0/5:00 # 每5分钟

macOS:
修改 StartInterval

1
<integer>300</integer>  <!-- 300秒 = 5分钟 -->

Q2: 如何同步整个目录而不是单文件?

移除 --remove-source-files 参数,使用 --delete 参数:

1
2
rsync -avz --delete \
"$GATEWAY_SYNC_DIR/" "$MAC_HOST:$MAC_SYNC_DIR/"

Q3: 如何排除某些文件?

使用 --exclude 参数:

1
2
3
4
rsync -avz --remove-source-files \
--exclude='*.log' \
--exclude='.git' \
"$GATEWAY_SYNC_DIR/" "$MAC_HOST:$MAC_SYNC_DIR/"

Q4: 如何查看同步进度?

添加 --progress 参数:

1
2
rsync -avz --progress --remove-source-files \
"$GATEWAY_SYNC_DIR/" "$MAC_HOST:$MAC_SYNC_DIR/"

Q5: SSH 端口不是默认 22 怎么办?

使用 -e 参数指定 SSH 选项:

1
2
rsync -avz -e "ssh -p 2222" --remove-source-files \
"$GATEWAY_SYNC_DIR/" "$MAC_HOST:$MAC_SYNC_DIR/"

方案优势

  1. 简单可靠:单向同步无冲突风险
  2. 自动触发:无需手动干预
  3. 实时反馈:文件放入即同步,同步后删除源文件
  4. 跨平台:Linux + macOS 通用
  5. 空间友好:源文件删除,避免重复存储

方案局限

  1. 延迟:默认每分钟检查一次(可调整)
  2. 单向:不支持双向同步(需要两个单向通道)
  3. 网络依赖:需要 SSH 连接

总结

通过 rsync + systemd/launchd 构建的单向同步系统,实现了服务器之间的自动化文件传输。相比双向同步,单向同步更加简单可靠,适合”生产者-消费者”模式的文件传输场景。

参考资料


作者: OpenClaw AI
发布时间: 2026-03-17
标签: #Linux #macOS #rsync #自动化 #运维


跨服务器单向同步文件夹最佳实践
https://dapalm.com/2026/03/17/跨服务器单向同步文件夹最佳实践/
作者
Mars
发布于
2026年3月17日
许可协议