痛点拆解:无人值守不是「同一条命令复制粘贴」
痛点 1:交互式成功、计划任务失败。Terminal 里 rsync 正常,cron/launchd 却卡在握手后或列表阶段。常见根因是PATH 与 SSH_AUTH_SOCK:计划任务不加载交互式 ~/.zshrc,也不会继承你手动 ssh-add 的会话。遠端 Mac 作 CI 节点时,还要核对运行用户与 WorkingDirectory。
痛点 2:openrsync「阈值式」卡死。Sequoia 默认 openrsync 在海量小文件或高变更目录下,可能在传输数百至千余文件后无限等待,无显式错误。与带宽抖动不同:CPU 低、日志静默。夜间同步与小时级增量最受伤。
痛点 3:SFTP 批处理半交互。sftp -b 遇权限或路径需确认时,非 TTY 下会静默等待输入;未配置 StandardErrorPath 的 plist 更难排查。
痛點 4:與原子發佈/校驗脫節。修 rsync 仍原地覆寫生產目錄會把損壞自動化。請並聯 原子發佈 與 SHA256 閘門。
现象分层:先判断「环境挂」还是「协议栈挂」
L0:同用户下 ssh -o BatchMode=yes 先通,再谈 rsync。失败则查密钥、known_hosts、跳板与双栈。L1:区分卡在 file list 还是单文件字节流。L2:客户端 openrsync 与远端 GNU rsync 组合易踩边界;先试 --protocol=28 与 --rsync-path 统一二进制。
launchd 另查 LimitNOFILE、Daemon 与 Agent 的钥匙串上下文。带口令密钥在无人值守场景优先改为机器入口专用密钥或受控 ssh-agent。
可引用数据与观测基线:把「偶发」写成可回归指标
建议先跑24h 基线:起止时间、文件数、字节、退出码、无进度秒数(超过约300s无增量则 timeout 告警)。CI 可把成功定义为传输 + 校验 + 原子切换三步各自有码,量化 openrsync 的平均重跑次数。
决策矩阵:何时改协议、何时换二进制、何时动环境
| 症状 | 高概率根因 | 首选动作 | 风险与回滚 |
|---|---|---|---|
| 仅 cron/launchd 卡住,交互式正常 | PATH、SSH_AUTH_SOCK、缺 TTY | 在脚本显式 export;ssh-add -l 前置检查;必要时 BatchMode=yes 失败早退出 | 误用全局环境可能影响同机其他 Job;用专用 plist 隔离 |
| 大目录传一段后永久停转 | openrsync 与对端实现组合边界 | 追加 --protocol=28;--rsync-path=/opt/homebrew/bin/rsync(示例路径以你机为准) | 远端路径错误会导致立即失败;先在 staging 目录 dry-run |
| SFTP 批处理挂起 | batch 需确认或权限错 | sftp -v;拆分;显式 bye | 日志脱敏 |
实操步骤(How-to):从「能跑」到「无人值守也能跑」
七步顺序执行;有新证据则回到分层假设,勿堆参数。
- 固定身份与环境快照:在脚本首部打印
id、pwd、umask、精简后的env | sort(脱敏)。对 launchd,确认UserName与WorkingDirectory与手动测试一致。 - 验证非交互 SSH:使用
ssh -o BatchMode=yes -o ConnectTimeout=10对遠端 Mac 做探测;失败则先修密钥与authorized_keys,不要进入 rsync。 - 对齐 rsync 实现:本机与远端统一为同一供应商的 rsync(常见为 GNU 3.x),通过
--rsync-path显式指定远端二进制;对 Sequoia 默认 openrsync 先尝试--protocol=28再评估是否安装 Homebrew rsync。 - 处理密钥与 agent:对无人值守,优先使用专用 CI 密钥并限制在 chroot 或专用上传目录;若必须口令,使用
ssh-agent子进程在 plist 内先行ssh-add,并限制密钥文件 ACL。 - 超时与重试:
timeout包裹rsync,指数退避;记录重试成功次序。 - dry-run:先在
staging/校验;并联 原子发布。 - 归档日志:按日切割日志,月度看「重跑率」与失败类型占比。
示例:launchd 调用时显式 PATH 与 rsync 路径(请按实际安装位置修改)
#!/bin/bash
set -euo pipefail
export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export RSYNC_RSH="ssh -o BatchMode=yes -o ServerAliveInterval=30"
/usr/bin/rsync -av --protocol=28 --rsync-path=/opt/homebrew/bin/rsync \
./artifacts/ "[email protected]:/data/inbox/staging/"強相關閱讀:把單點修復放進體系化交付
並行與限流見 並發 SFTP;握手尾延遲見 ControlMaster;目錄隔離見 Chroot 與 多團隊協作。
自建節點要扛硬體、系統小版本與 plist 行為漂移;隱性成本累加後,租賃按交付場景調優的裸機遠端 Mac常更省時、少事故面。
FAQ 与托管结论
是否建议彻底禁用系统 rsync?
不必一刀切:小目录本地拷贝可继续用系统工具;远程 + 海量 + 无人值守再评估 Homebrew 与 --rsync-path,版本写进基线。
总结:何时转向托管遠端 Mac?
若你已把 openrsync、agent、PATH、超时与校验写成可回归配置,自建可行。若缺专职运维却要7×24 入口与跨区稳定,脚本债会反噬业务。租赁 SFTPMAC 遠端 Mac可把目录隔离与观测基线产品化,你保留流水线与密钥策略,节点稳定性交给专业侧。
