【问题标题】:Run a shell script periodically on Mac OS X without root permission在没有 root 权限的情况下在 Mac OS X 上定期运行 shell 脚本
【发布时间】:2014-07-15 09:09:11
【问题描述】:

我想在不使用 root 的情况下在 mac os x 上启动 .sh 类型或 .py 的文件, 我在谷歌搜索,发现launchctl可以帮助我,

所以我阅读教程并在教程中做同样的事情,但它对我不起作用,[我使用 mac os x 10.9 x64]

我的 .plist 文件 [每 60 秒运行 1.sh 文件]:

<?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.alvin.crontabtest</string>
  <key>ProgramArguments</key>
  <array>
    <string>/Users/paul/Desktop/1.sh</string>
  </array>
  <key>Nice</key>
  <integer>1</integer>
  <key>StartInterval</key>
  <integer>60</integer>
  <key>RunAtLoad</key>
  <true/>
  <key>StandardErrorPath</key>
  <string>/tmp/AlTest1.err</string>
  <key>StandardOutPath</key>
  <string>/tmp/AlTest1.out</string>
</dict>
</plist>

1.sh 的来源:

echo '+' >> /Users/paul/Desktop/worked.txt

我把 Run.plist 放在 /Users/paul/Run.plist 中

并从终端运行命令:

launchctl load /Users/paul/Run.plist
Launchctl start com.alvin.crontabtest

命令执行没有任何错误,但我看不到 working.txt 中的任何内容

谁能帮帮我?

【问题讨论】:

  • 检查控制台是否有错误

标签: macos bash cron startup launchd


【解决方案1】:

您不想使用普通的 crontab 有什么特别的原因吗?

% echo "* * * * * /Users/paul/Desktop/1.sh" | crontab -

此命令应添加一个每分钟运行一次的 cron 作业。

请注意,此命令还将替换您已有的任何 crontab。应谨慎使用 crontab - 命令,作为捷径。

如果您想编辑现有的 crontab,以避免删除之前设置的作业,您可以使用 crontab -e。 (如果它启动 vim 而您不知道如何使用 vim,您可以按 ESC 退出:q!回车然后去找编辑器文档。)

如果您需要有关如何编辑 crontab 的说明,请在您的 shell 中输入 man crontab。如果您需要有关 crontab 文件的语法信息,man 5 crontab 会告诉您。

享受吧!


更新:(每 cmets)

每 30 秒运行一次作业需要一个简单的技巧。 Cron 仅按每分钟运行一次作业,因此要每 30 秒运行一次,您可以有两个作业,其中一个有 30 秒的延迟。例如:

  #Mn Hr Da Mo DW Command
  *   *  *  *  *   /Users/paul/Desktop/1.sh
  *   *  *  *  *   sleep 30; /Users/paul/Desktop/1.sh

希望这会有所帮助。

【讨论】:

  • 谢谢,但你能给我命令同样的命令,每 30 秒执行一次吗?或者一些我可以设置秒的命令,它也会在重置电脑后的启动中执行?
  • 它已添加到我的 cron 作业中,但没有执行! 2 分钟后,我必须在 echo "* * * * * /Users/paul/Desktop/1.sh" 之后运行任何命令 | crontab ?
  • 虽然cron/crontab 建议在原则上很有帮助,但您的建议归结为:“您在做某事时遇到了麻烦。与其让我帮助您,不如让您尝试不同的东西?”。虽然这可能适用于存在根本缺陷的方法,但在目前的情况下。事实上,OP 的问题根本不在于launchd.plist 文件,而在于他/她的脚本本身。请参阅我的回答,了解在 OS X 上使用 cronlaunchd 的优缺点。
  • 请不要将The command I gave you, with the dash at the end, will install the quoted output as a crontab, **replacing any crontab that is currently in place**(强调我的)埋在评论中。当一个天真的读者在你的答案中尝试了代码 sn-p 时,他们可能已经在不知不觉中清除了他们现有的 crontab 文件。
  • 感谢您解释和更新您的答案。我同意了解cron 作为一种更简单且可移植的替代方案是有帮助的; launchd 确实很容易出错(尽管在手头的情况下,看看 Console.app 会发现问题)。
【解决方案2】:

澄清一下:OP 的.plist 文件本身 完全正常 - 问题出在 内部 调用的 shell 脚本(未在问题中显示)。

在 OS X 上,使用由 CLI launchctl 加载并由守护进程管理器 launchd 调用的 .plist 文件是调度(重复)任务的首选方式 (更多信息见下文)。

注意事项:

  • launchd.plist 文件的格式man launchd.plist 中描述
  • 对于每次当前用户登录时要加载的.plist文件,它必须放在~/Library/LaunchAgents/ all-users 文件必须放在 /Library/LaunchAgent/ - 需要 root 权限)。
  • 指定输出捕获文件,使用键 StandardOutPathStandardErrorPath 表示连续调用附加到指定的文件,这意味着这些文件保留无限增长,除非外部管理
  • 关于疑难解答:@Grady Player 的建议适用:启动 Console.app 并查找 com.apple.launchd.peruser 条目 - 调用 .plist 中指定的命令失败会在那里显示。

@ghoti's answer 描述了launchdcron(通常用于 Linux)的通用 Unix 替代

至于cron 与 OS X 的关系:@ghoti 问:

您不想使用普通的 crontab 有什么特别的原因吗?

在 OS X 上,man crontab 建议(已添加重点):

虽然官方支持 cron(8) 和 crontab(5) 在 Darwin [OS X] 下,它们的功能已被吸收到 launchd(8), 它提供了一种更灵活的自动执行命令的方式。 有关详细信息,请参阅 launchctl(1)。

底线是这样的:

  • 如果您来自 *nix 背景,您可能更愿意继续使用 croncrontab,假设:
    • 您知道可能存在通过launchd 安排的其他后台任务。
    • 您了解cron 的局限性,并且可以使用/绕过它们。
  • 否则,在 OS X 上
    • 许多第三方应用程序使用原生launchd 功能,因此通过.plist 文件在/Library/LaunchAgents(适用于所有用户)或~/Library/LaunchAgents(适用于当前用户)中指定定期后台任务。
    • 如果您想将后台任务集中管理到这些位置和/或您想利用launchd 提供的更高灵活性,请通过.plist 评估的文件指定后台任务@ 987654353@.

添加简单cron 任务可能比为launchd 创建.plist 文件更简单,但是Lingon 3 等第3 方实用程序可以为后者提供帮助。

此外,cron 任务的调用方式与每个用户 launchd 任务的调用方式存在细微差别:例如,前者不允许通过 AppleScript 进行用户交互,而后者做。


以增加launchd 的灵活性为例:OP 在后续评论中要求任务每 30 秒运行一次:

  • cron 任务的最小间隔为 60 秒,因此需要在 @ghoti 的回答中使用解决方法。

  • 相比之下,使用launchd .plist 文件,将&lt;key&gt;StartInterval&lt;/key&gt;&lt;integer&gt;60&lt;/integer&gt; 更改为&lt;key&gt;StartInterval&lt;/key&gt;&lt;integer&gt;30&lt;/integer&gt; 就足够了。

【讨论】:

  • @KaushikNayak:谢谢 - 不确定这是暂时的故障还是链接真的死了。为避免混淆,我已将其删除 - 您可以随时通过 man launchd.plist 获取信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 2018-08-15
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 2021-09-06
相关资源
最近更新 更多