【问题标题】:How do I set a task to run every so often?如何将任务设置为每隔一段时间运行一次?
【发布时间】:2010-09-13 01:47:58
【问题描述】:

如何让脚本每隔 30 分钟运行一次?我认为不同的操作系统有不同的方法。我正在使用 OS X。

【问题讨论】:

    标签: macos shell time cron scheduled-tasks


    【解决方案1】:

    只需使用 launchd。它是一个非常强大的启动器系统,同时它是 Mac OS X 的标准启动器系统(当前的 OS X 版本没有它甚至无法启动)。对于不熟悉launchd(或一般OS X)的人来说,它就像initcronat、SysVinit (init.d)、inetd、@987654331 之间的杂交@ 和 systemd。借用所有这些项目的概念,同时提供您在其他地方可能找不到的东西。

    每个服务/任务都是一个文件。文件的位置取决于以下问题:“该服务应该何时运行?”和“服务需要哪些权限?”

    系统任务转到

    /Library/LaunchDaemons/
    

    如果他们应该运行,无论是否有任何用户登录到系统。它们将以“root”权限启动。

    如果他们只在任何用户登录时运行,他们会去

    /Library/LaunchAgents/
    

    并且会以刚刚登录的用户的权限执行。

    如果它们只有在登录时才运行,它们会转到

    ~/Library/LaunchAgents/
    

    其中 ~ 是您的 HOME 目录。这些任务将以您的权限运行,就像您通过命令行或双击 Finder 中的文件自己启动它们一样。

    注意,/System/Library/LaunchDaemons/System/Library/LaunchAgents 也存在,但像往常一样,/System 下的所有内容都由 OS X 管理。你不能在那里放置任何文件,你不能在那里更改任何文件,除非你真的知道你在做什么。在 Systems 文件夹中乱搞可能会使您的系统无法使用(使其进入甚至拒绝再次启动的状态)。这些是 Apple 放置 launchd 任务的目录,这些任务可以让您的系统在引导期间启动并运行、根据需要自动启动服务、执行系统维护任务等等。

    每个launchd 任务都有一个 plist 格式的文件。它应该有反向域名表示法。例如。你可以命名你的任务

    com.example.my-fancy-task.plist
    

    这个 plist 可以有各种选项和设置。单手写一个是次优的,您可能希望获得免费工具Lingon 来创建您的任务。这个工具以前是免费的,现在在应用商店售价 5 美元,非应用商店版本售价 10 美元(非应用商店版本功能更强大,如果您已经打算付费,请认真购买非应用商店版本)。如果有人知道免费软件或开源的类似工具,请在 cmets 中给我留言,我宁愿推荐一个(不想在这里为商业软件做广告)。

    作为一个例子,它可能看起来像这样

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.example.my-fancy-task</string>
        <key>OnDemand</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/sh</string>
            <string>/usr/local/bin/my-script.sh</string>
        </array>
        <key>StartInterval</key>
        <integer>1800</integer>
    </dict>
    </plist>
    

    此代理将每 1800 秒(每 30 分钟)运行一次 shell 脚本 /usr/local/bin/my-script.sh。您还可以在某些日期/时间运行任务(基本上,launchd 可以做 cron 可以做的所有事情),或者您甚至可以禁用“OnDemand”导致launchd 保持进程永久运行(如果它退出或崩溃,launchd 将立即重新启动它) .您甚至可以限制一个进程可以使用多少资源(如前所述,Lingon 在一个漂亮的 UI 界面中显示所有这些设置)。

    更新: 尽管OnDemand 仍受支持,但它已被弃用。新设置被命名为KeepAlive,这更有意义。它可以有一个布尔值,在这种情况下,它与OnDemand 完全相反(将其设置为false 就像OnDemandtrue 一样,反之亦然)。伟大的新功能是,它还可以有一个字典值而不是布尔值。如果它有一个字典值,你有几个额外的选项可以让你更精细地控制在哪些情况下任务应该保持活动状态。例如。只有当程序以 0 的退出代码终止时,它才会保持活动状态,只要磁盘上的某个文件/目录存在,只有另一个任务也处于活动状态,或者只有网络当前已启动。 em>

    您也可以通过命令行手动启用/禁用任务:

    launchctl <command> <parameter>
    

    命令可以是加载或卸载,加载或再次卸载它,在这种情况下参数是文件的路径。或者 command 可以是 start 或 stop ,只是启动或停止这样的任务,在这种情况下,参数是标签(com.example.my-fancy-task)。其他命令和选项也存在。

    请参阅 Apple 的 plist formatlaunchctl command line tool 文档(请注意,您可以在顶部选择 OS X 版本,因为不同 OS X 版本之间的格式/选项会有所不同)

    【讨论】:

    • 如果我作为用户想要在我没有登录的情况下运行某些东西怎么办?这可能吗,还是我必须让管理员在 /Library/LaunchDaemons 中放一些东西?
    • @Mark:是的,您的管理员必须这样做,并且必须在 .plist 文件中适当地设置 UserName 和 GroupName 键。
    • LaunchControl soma-zone.com/LaunchControl 非常有用,它可以无限试用,据我所知,与许可版本相比没有任何限制。
    • @MaciekRek StartCalendarInterval 具有两个字典的数组,两个字典都具有键 Minute 和一次 00 和一次 30 的值将完全符合您的要求。请以后将问题作为问题,而不是作为 cmets,然后我也可以向您展示最终的字典(我不能在评论中这样做)。这个网站是关于提问的。如果您想在问题中提示某人,请将问题的链接作为评论发布,而不是问题本身。
    • @Noumenon 是的,他们会的。请记住,当系统处于锁定状态时,无法访问某些钥匙串项目,因此您的任务需要访问钥匙串中的任何内容,此访问可能会失败。即使你快速的用户切换到另一个用户,他们也会继续运行。唯一会阻止它们运行的​​是您的系统进入睡眠状态或您的用户退出系统。
    【解决方案2】:

    您可以使用非常方便的 plist 生成器:http://launched.zerowidth.com/(无需购买任何东西……)

    它将为您提供一个 shell 单行程序,以使用已推荐的 launchd

    注册新的计划作业

    【讨论】:

      【解决方案3】:

      在 MacOSX 上,您至少有以下选项:

      从个人经验来看,cron 是最可靠的。当我测试时,launchd 有许多错误和怪癖。 iCal 警报仅在您登录时运行(但这可能是您喜欢的方式)。

      【讨论】:

        【解决方案4】:

        正如 Mecki 所指出的,launchd 将是解决这个问题的方法。 launchd 有一个名为 Lingon 的 GUI 界面,您可能想查看它,而不是手动编辑 launchd 文件:

        Lingon 是一个用于创建编辑启动的图形用户界面 Mac OS X Leopard 10.5 的配置文件。

        [剪辑...]

        在这个版本中编辑配置文件比以往任何时候都容易 它有两种不同的模式。最常见的基本模式 设置在非常简单的界面和专家模式中随时可用 您可以在其中直接在文本中添加所有设置或插入 他们通过菜单。

        【讨论】:

        • 老实说,这是一个很棒的、易于使用的界面,只需完成它并让您继续前进。如果你的时间不够,这就是你要走的路。
        【解决方案5】:

        您可以使用 cron 来安排任务。

        crontab -e
        

        按以下格式指定作业。

        * * * * *  command to execute
        │ │ │ │ │
        │ │ │ │ └─── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
        │ │ │ └──────── month (1 - 12)
        │ │ └───────────── day of month (1 - 31)
        │ └────────────────── hour (0 - 23)
        └─────────────────────── min (0 - 59)
        

        例子:

        0 12 * * *  cd ~/backupfolder && ./backup.sh
        

        安装 cron 任务后,您可以使用 crontab -l 列出您的任务。

        crontab -l
        

        如果您想了解更多关于 cron 调度表达式的信息,可以访问

        https://crontab.guru https://ole.michelsen.dk/blog/schedule-jobs-with-crontab-on-mac-osx.html

        【讨论】:

          【解决方案6】:

          MAC OS 有一个Automator 工具,与windows 中的Task Scheduler 相同。使用 Automator,您可以每天安排任务,并将任务与重复的日历事件链接,以在每天指定的时间运行脚本。参考链接to run scripts on daily basis in Mac OS

          【讨论】:

          • 至少在 macOS Catalina (10.15.x) 中,我找不到通过 Automator 在日历中安排任务的方法。我使用 Lingon 获得了更好的结果(请参阅作为启动界面提到的其他答案)。
          【解决方案7】:

          对于苹果脚本,我设置了一个特殊的 iCal 日历并使用警报定期运行它们。对于命令行工具,我使用 launchd。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多