MacOS平台设置定时运行的任务记录

最近考虑到iCloud的速度较慢,且偶尔会出现问题时,放弃iCloud,而是转而使用坚果云来进行多台主机之间的数据同步。

坚果云同步是会遇到一些隐藏文件无法同步的问题, 但是我也不需要同步这些隐藏文件, 包括恼人的 .DS_Store 文件, 因此我需要一个定时任务来定期清理这些文件。在 macOS 平台上,传统的 crontab 命令确实不太实用,因为 macOS 已经采用了 launchd 作为任务管理器。launchd 提供了更强大和灵活的方式来管理计划任务,允许你以更直观的方式创建和管理定时任务。

在 macOS 平台上,使用 launchd 来设置定时运行的任务。launchd 是一个系统级的守护程序,用于管理和监控各种系统和用户级任务。以下是如何使用 launchd 在 macOS 上设置定时运行的任务的步骤:

  1. 创建一个属性列表(plist)文件:

    使用文本编辑器创建一个属性列表文件,该文件包含有关你的任务的描述,包括任务的类型、触发器和执行内容。属性列表文件的文件扩展名应为 .plist

    你可以使用以下示例属性列表作为参考,并根据你的需求进行修改:

    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
    <?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.vix.cron</string>
    <key>ProgramArguments</key>
    <array>
    <string>这里存放需要执行的脚本地址</string>
    </array>

    <key>Nice</key>
    <integer>1</integer>

    <key>StartInterval</key>
    <integer>30</integer>

    <key>RunAtLoad</key>
    <true />

    <key>StandardErrorPath</key>
    <string>/tmp/test.err</string>

    <key>StandardOutPath</key>
    <string>/tmp/test.out</string>
    </dict>
    </plist>

    这个示例会每30秒执行一次脚本文件 /path/to/your/script.sh

    我的定时清理 .DS_Store 文件脚本参考如下:

    1
    2
    3
    #!/bin/bash
    find ~/Documents -name ".DS_Store" -depth -exec rm -rf {} \;
    find ~/Desktop -name ".DS_Store" -depth -exec rm -rf {} \;
  2. 将 plist 文件保存到适当的位置:

    1
    ~/Library/LaunchAgents/

    1
    /Library/LaunchDaemons/

    如果你想为当前用户设置任务,将 plist 文件保存到 ~/Library/LaunchAgents/;如果你想为系统设置任务,将 plist 文件保存到 /Library/LaunchDaemons/

  3. 加载任务:

    使用以下命令加载你的任务:

    1
    launchctl load /path/to/your/plist/file.plist

    如果你将 plist 文件保存到 ~/Library/LaunchAgents/,则使用以下命令:

    1
    launchctl load ~/Library/LaunchAgents/yourfile.plist

    如果你将 plist 文件保存到 /Library/LaunchDaemons/,则使用以下命令:

    1
    sudo launchctl load /Library/LaunchDaemons/yourfile.plist
  4. 启动或重新启动任务:

    任务会根据属性列表中定义的时间触发。你还可以使用 launchctl 命令手动启动或重新启动任务:

    1
    launchctl start com.example.myjob

    1
    sudo launchctl start com.example.myjob

    请替换 com.example.myjob 为你的任务的 Label 值。

  5. 停止任务:

    你可以使用以下命令停止任务:

    1
    launchctl unload xxx

  6. 查看任务状态:

    你可以使用以下命令查看任务的状态:

    1
    launchctl list | grep com.example.myjob

    请替换 com.example.myjob 为你的任务的 Label 值。

    你还可以使用以下命令查看任务的日志:

    1
    tail -f /tmp/test.out

    请替换 /tmp/test.out 为你的任务的 StandardOutPath 值。

  7. 更多的定时任务设置:

    launchd 提供了多种方式来设置更精细的定时任务,可以根据分钟、小时等更加精确的时间间隔来执行任务。以下是一些示例:

    • 按分钟执行任务

    如果你希望定时任务每隔一定的分钟数执行一次,你可以使用 StartInterval 键来设置间隔。下面是一个示例:

    1
    2
    <key>StartInterval</key>
    <integer>600</integer>

    这将使任务每隔 10 分钟执行一次。

    • 按小时执行任务

    如果你希望任务按小时执行,你可以结合使用 StartCalendarIntervalStartInterval。例如,要在每小时的第 30 分钟执行任务:

    1
    2
    3
    4
    5
    6
    7
    <key>StartCalendarInterval</key>
    <dict>
    <key>Minute</key>
    <integer>30</integer>
    </dict>
    <key>StartInterval</key>
    <integer>3600</integer>

    这将使任务每隔一小时执行一次,并在每小时的第 30 分执行。

    • 按天执行任务

    如果你需要在特定时间执行任务,可以使用 StartCalendarInterval,如下所示:

    1
    2
    3
    4
    5
    6
    7
    <key>StartCalendarInterval</key>
    <dict>
    <key>Hour</key>
    <integer>8</integer>
    <key>Minute</key>
    <integer>0</integer>
    </dict>

    这将使任务在每天早上 8 点执行。

    • 按周执行任务

    你可以使用 StartCalendarInterval 来指定具体的星期几执行任务,例如,每周一早上 8 点:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <key>StartCalendarInterval</key>
    <dict>
    <key>Hour</key>
    <integer>8</integer>
    <key>Minute</key>
    <integer>0</integer>
    <key>Weekday</key>
    <integer>1</integer>
    </dict>

    这将使任务每周一早上 8 点执行。

    通过合理设置 StartIntervalStartCalendarInterval,你可以创建几乎任何你想要的定时任务规则,以满足不同的需求。请根据你的具体需求修改上述示例来创建自定义的定时任务。

你的任务现在应该会按计划执行。你可以根据需要编辑 plist 文件来更改触发时间或其他任务设置。