在没有root权限的情况下,在Mac OS X上定期运行shell脚本

use*_*325 10 macos bash cron startup launchd

我想在不使用root的情况下在mac os x上启动.sh类型或.py文件,我在google搜索并发现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>
Run Code Online (Sandbox Code Playgroud)

1.sh的来源:

echo '+' >> /Users/paul/Desktop/worked.txt
Run Code Online (Sandbox Code Playgroud)

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

并从终端运行命令:

launchctl load /Users/paul/Run.plist
Launchctl start com.alvin.crontabtest
Run Code Online (Sandbox Code Playgroud)

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

有人可以帮我吗?

mkl*_*nt0 24

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

在OS X上,使用.plist由CLI加载并由launchctl守护程序管理器调用的文件launchd是调度(重复)任务的首选方式(有关详细信息,请参阅下文).

注意事项:

  • 格式launchd .plist的文件中描述man launchd.plist
  • 对于.plist每次当前用户登录时要加载的文件,必须将其放入~/Library/LaunchAgents/(所有用户文件必须放入/Library/LaunchAgent/- 需要root权限).
  • 使用键指定输出捕获文件StandardOutPathStandardErrorPath表示连续调用附加到指定的文件,这意味着这些文件将无限增长,除非在外部进行管理.
  • 重新排除故障:@Grady Player的建议适用:启动Console.app并查找com.apple.launchd.peruser条目 - 未能调用在.plist那里显示的命令.

@ ghoti的答案描述了一般的Unix的替代launchd,cron(通常在Linux上使用):

至于如何cron与OS X相关:@ghoti问:

您不想使用普通crontab的任何特殊原因?

在OS X上,man crontab建议(强调添加):

尽管在Darwin [OS X]下正式支持cron(8)和crontab(5),但它们的功能已被吸收到launchd(8)中,这提供了一种更灵活的自动执行命令的方法.有关更多信息,请参阅launchctl(1).

底线是这样的:

  • 如果你来自一个*nix的背景下,你可能会更舒服继续使用croncrontab假设:
    • 您知道launchd可能存在其他后台任务,这些任务是通过计划进行的.
    • 你知道它cron的局限性,可以和它们一起使用.
  • 否则,在OS X上:
    • 许多第三方应用程序使用本机launchd功能,因此通过(针对所有用户)或(针对当前用户)中的.plist文件指定周期性后台任务./Library/LaunchAgents~/Library/LaunchAgents
    • 如果你想集中的后台任务管理,这些位置和/或要采取的增加灵活性的优势launchd提供,请通过指定后台任务.plist的评估文件launchd.

添加简单 cron任务可能比创建.plist文件更简单launchd,但第三方实用程序(如Lingon 3)可以帮助后者.

此外,在调用任务与每用户任务之间存在细微差别:例如,前者不允许通过AppleScript进行用户交互,而后者则不允许.cronlaunchd


例如,增加了灵活性launchd:OP在后续评论中要求每30秒执行一次任务:

  • 任务最小间隔为cron60秒,需要@ ghoti答案中的解决方法.

  • 相比之下,与launchd .plist文件,改变<key>StartInterval</key><integer>60</integer><key>StartInterval</key><integer>30</integer>就够了.


gho*_*oti 7

您不想使用普通crontab的任何特殊原因?

% echo "* * * * * /Users/paul/Desktop/1.sh" | crontab -
Run Code Online (Sandbox Code Playgroud)

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

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

如果要编辑现有的crontab,以避免删除以前设置的作业,则可以使用crontab -e.(如果它启动但vim你不知道如何使用vim,你可以通过点击退出ESC:q!Enter然后去查找编辑器文档.)

如果您需要有关如何编辑crontabs的说明,请man crontab在shell中键入.如果您需要有关crontab文件的语法信息,man 5 crontab将显示该信息.

请享用!


更新:(每条评论)

每30秒运行一次工作需要一个简单的黑客攻击.Cron只能按分钟运行作业,所以每30秒运行一次,你可以有两个作业,其中一个有30秒的延迟.例如:

  #Mn Hr Da Mo DW Command
  *   *  *  *  *   /Users/paul/Desktop/1.sh
  *   *  *  *  *   sleep 30; /Users/paul/Desktop/1.sh
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 虽然`cron` /`crontab`建议在原则上是有帮助的,但你的建议归结为:"你做某事有困难.而不是我帮助你,你为什么不尝试不同的东西?".虽然这可能适用于根本上有缺陷的方法,但事实并非如此.事实上,OP的问题根本不在于`launchd`的`.plist`文件,而在于他/她的_script本身_.请参阅我的答案,了解在OS X上使用`cron`与`launchd`的优缺点. (3认同)
  • 请不要埋没`我给你的命令,最后用破折号将安装引用的输出作为crontab,**替换当前所有的crontab**(强调我的)_comment_.当一个天真的读者在你的答案中尝试了代码片段时,他们可能会在不知不觉中消灭了他们现有的`crontab`文件. (2认同)