macOS:使用launchd和rsync在两个卷之间同步文件

662 阅读3分钟

在驱动器之间备份和同步文件和目录对许多用户来说是非常普遍的使用情况。在这个快速教程中,你将学习如何使用launchdrsync在 macOS 的不同卷之间同步文件。

问题

在macOS的两个驱动器之间双向同步一个(KeePass)文件。

解决方法

  • 注意两个地方的文件变化
  • 在不同地点之间同步文件,只在源文件比目标文件新的情况下进行更新。

实施

观察文件的变化launchd

监视文件或目录变化的最简单方法是使用launchdlaunchd是一个 macOS 服务,用于启动、停止和管理守护进程、应用程序、进程和脚本。launchd使用属性列表*(plist*)文件来配置程序的运行方式。在这种情况下,我们想在文件或目录发生变化时运行程序。

该配置如下:

<?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>file.sync</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/kolorobot/.scripts/file.sync.sh</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Volumes/Kolorodisk/My Files/KeePass/my-db.kdbx</string>
        <string>/Users/kolorobot/KeePass/my-db.kdbx</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/tmp/file.sync.err</string>
    <key>StandardOutPath</key>
    <string>/tmp/file.sync.out</string>
</dict>
</plist>

上述配置可以读作以下内容:

  • 工作的名称是file.sync
  • 要运行的程序是/Users/kolorobot/.scripts/file.sync.sh
  • 当两个文件有变化时,要运行该程序。
    • /Volumes/Kolorodisk/My Files/KeePass/my-db.kdbx
    • /Users/kolorobot/KeePass/my-db.kdbx
  • 标准输出被重定向到/tmp/file.sync.out
  • 标准错误被重定向到/tmp/file.sync.err

注意在路径中没有使用转义字符spacebar

代表当前登录的用户执行该作业。

launchd可以作为系统用户或当前登录的用户执行作业。我们将使用第二种情况,为此:

  • 将文件存储在~/Library/LaunchAgents/file.sync.plist
  • 在终端,执行launchctl load -w ~/Library/LaunchAgents/file.sync.plist 来加载定义。

要卸载定义,请运行。launchctl unload -w ~/Library/LaunchAgents/file.sync.plist

同步文件

为了同步文件,我们将使用rsync ,但它将通过前面提到的方式启动。file.sync.sh

这个文件的内容:

#!/bin/sh
SRC="/Volumes/Kolorodisk/My Files/KeePass/my-db.kdbx"
DST="/Users/kolorobot/KeePass/my-db.kdbx"

if [ -d  /Volumes/Kolorodisk ]
then
    echo "---- Sync ----"
    rsync -rtuv "$SRC" "$DST"
    rsync -rtuv "$DST" "$SRC"
    /usr/bin/osascript -e 'display notification "File sync complete!" with title "Sync"'
fi
  • ~/.scripts 中创建file.sync.sh 并使其可执行。
  • 粘贴上述内容,并通过执行它来验证脚本是否工作。

这个脚本是做什么的?

  • 它检查外部驱动器是否被安装
  • 它使用rsync两个方向上同步该文件。只有当源文件目标文件新时,文件才会被复制。
  • 它显示系统通知

全磁盘访问bin/sh

随着macOS Catalina启动守护程序和启动代理引入了新的用户隐私保护(https://developer.apple.com/documentation/macos_release_notes/macos_catalina_10_15_release_notes),简而言之,由launchd运行的程序需要被授权访问外部驱动器。如果操作不当,你可能会看到以下错误。

sync: send_files failed to open "/Volumes/Kolorodisk/My Files/KeePass/my-db.kdbx": Operation not permitted (1)
rsync error: some files could not be transferred (code 23) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54/rsync/main.c(996) [sender=2.6.9]

解决这个问题的最简单方法是在bin/sh ,给予全盘访问权,System Preferences > Security & Privacy > Privacy > Full Disk Access

测试解决方案

当所有设置完成后,你可以通过对同步文件进行修改来测试该解决方案。

参见