简体   繁体   English

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

[英]Run a shell script periodically on Mac OS X without root permission

I want to start up a file with .sh type or .py on mac os x without using root , I searched in google and found launchctl can help me , 我想在不使用root的情况下在mac os x上启动.sh类型或.py文件,我在google搜索并发现launchctl可以帮助我,

so i read tutorial and do same in tutorial but it not work for me , [i using mac os x 10.9 x64] 所以我读教程并在教程中做同样但它不适合我,[我使用mac os x 10.9 x64]

My .plist file [run 1.sh file in every 60second] : 我的.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>

source of 1.sh: 1.sh的来源:

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

I put Run.plist in /Users/paul/Run.plist 我将Run.plist放在/Users/paul/Run.plist中

and run command from terminal : 并从终端运行命令:

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

commands execute without any error but i not see anything in worked.txt 命令执行没有任何错误,但我没有看到working.txt中的任何内容

can anyone help me please ? 有人可以帮我吗?

To clarify: The OP's .plist file itself was perfectly OK - the problem turned out to be inside the shell script invoked (not shown in the question). 澄清一下: OP的.plist文件本身就完全没问题 - 问题原来是调用的shell脚本中(问题中没有显示)。

On OS X, using .plist files loaded by CLI launchctl and invoked by daemon manager launchd is the preferred way of scheduling (recurring) tasks (see below for more). 在OS X上,使用由CLI launchctl加载并由守护程序manager launchd调用的.plist文件是调度(重复)任务的首选方法 (有关详细信息,请参阅下文)。

Things to note: 注意事项:

  • The format of launchd .plist files is described in man launchd.plist launchd .plist文件格式man launchd.plist描述
  • For a .plist file to be loaded every time the current user logs in , it must be placed in ~/Library/LaunchAgents/ ( all-users files must be placed in /Library/LaunchAgent/ - requires root privileges). 对于每次当前用户登录时要加载的.plist文件 ,必须将其放在~/Library/LaunchAgents/所有用户文件必须放在/Library/LaunchAgent/ - 需要root权限)。
  • Specifying output-capture files with keys StandardOutPath and StandardErrorPath means that successive invocations append to the files specified, which means that these files keep growing indefinitely , unless managed externally . 指定与键输出捕获文件 StandardOutPathStandardErrorPath意味着连续调用附加到指定的文件,这意味着这些文件一直无限增长 ,除非外部管理
  • Re troubleshooting : @Grady Player's advice applies: launch Console.app and look for com.apple.launchd.peruser entries - a failure to invoke the command specified in the .plist would show there. 重新排除故障 :@Grady Player的建议适用: 启动Console.app并查找com.apple.launchd.peruser条目 - 无法调用.plist指定的命令将显示在那里。

@ghoti's answer describes a general Unix alternative to launchd , cron (typically used on Linux): @ ghoti的答案描述了一个Unix的替代方案 ,即launchdcron (通常在Linux上使用):

As for how cron relates to OS X: @ghoti asks: 至于cron如何与OS X相关:@ghoti问:

Any particular reason you don't want to use a normal crontab? 您不想使用普通crontab的任何特殊原因?

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

Although cron(8) and crontab(5) are officially supported under Darwin [OS X], their functionality has been absorbed into launchd(8) , which provides a more flexible way of automatically executing commands . 尽管在Darwin [OS X]下正式支持cron(8)和crontab(5),但它们的功能已被吸收到launchd(8)中 ,这提供了一种更灵活的自动执行命令的方法 See launchctl(1) for more information. 有关更多信息,请参阅launchctl(1)。

The bottom line is this: 底线是这样的:

  • If you come from a *nix background , you may be more comfortable with continuing to use cron and crontab , assuming: 如果你来自* nix背景 ,你可能会更习惯继续使用croncrontab ,假设:
    • you're aware of the fact that additional background tasks, scheduled via launchd , may exist. 您知道可能存在通过launchd计划的其他后台任务。
    • you're aware of cron 's limitations and can work with/around them. 你知道cron的局限性,可以和他们一起工作。
  • Otherwise, on OS X : 否则,在OS X上
    • many third-party apps use the native launchd feature and thus specify periodic background tasks via .plist files in /Library/LaunchAgents (for all users) or ~/Library/LaunchAgents (for the current user). 许多第三方应用程序使用本机launchd功能,因此通过/Library/LaunchAgents (适用于所有用户)或~/Library/LaunchAgents (适用于当前用户)中的.plist文件指定定期后台任务。
    • If you want to centralize management of background tasks to these locations and/or you want to take advantage of the increased flexibility that launchd provides , go with specifying background tasks via .plist files evaluated by launchd . 如果要将后台任务的管理集中到这些位置和/或您希望利用launchd提供的更高灵活性 ,请通过launchd评估的.plist文件指定后台任务。

Adding simple cron tasks is probably simpler than creating .plist files for launchd , but 3rd-party utilities such as Lingon 3 can help with the latter. 添加简单的 cron任务可能比为launchd创建.plist文件更简单,但是像Lingon 3这样的第三方实用程序可以帮助后者。

Also, there are subtle differences in how cron tasks are invoked vs. per-user launchd tasks: for instance, the former do not allow user interaction via AppleScript, whereas the latter do. 此外,调用cron任务与每个用户launchd任务之间存在细微差别 :例如,前者不允许通过AppleScript进行用户交互,而后者则不允许。


Case in point re increased flexibility of launchd : the OP, in a follow-up comment, asks for the task to run every 30 seconds: 例如,增加了launchd灵活性:OP在后续评论中要求每30秒执行一次任务:

  • The minimum interval for cron tasks is 60 seconds , necessitating the workaround in @ghoti's answer. cron任务最小间隔是60秒 ,需要@ ghoti的答案中的解决方法。

  • By contrast, with the launchd .plist file, changing <key>StartInterval</key><integer>60</integer> to <key>StartInterval</key><integer>30</integer> is enough. 相比之下,使用launchd .plist文件,将<key>StartInterval</key><integer>60</integer>更改为<key>StartInterval</key><integer>30</integer>就足够了。

Any particular reason you don't want to use a normal crontab? 您不想使用普通crontab的任何特殊原因?

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

This command should add a cron job that runs once per minute. 此命令应添加每分钟运行一次的cron作业。

NOTE that this command will also replace any crontab that you already have. 请注意,此命令还将替换您已有的任何crontab。 The crontab - command should be used with caution, as a short-cut. crontab -命令应该谨慎使用,作为捷径。

If you want to edit an existing crontab, so as to avoid obliterating previously set jobs, you can use crontab -e . 如果要编辑现有的crontab,以避免删除以前设置的作业,可以使用crontab -e (If it launches vim and you don't know how to use vim , you can exit by hitting ESC : q ! Enter and then go find editor documentation.) (如果它启动vim并且您不知道如何使用vim ,则可以通过按ESC退出 q Enter然后查找编辑器文档。)

If you want instructions on how to edit crontabs, type man crontab at your shell. 如果您需要有关如何编辑crontabs的说明,请在shell中键入man crontab If you want syntax information on the crontab file, man 5 crontab will show you that. 如果你想要crontab文件的语法信息, man 5 crontab会告诉你。

Enjoy! 请享用!


UPDATE: (per comments) 更新:(每条评论)

To run your job every 30 seconds requires a simple hack. 每30秒运行一次工作需要一个简单的黑客攻击。 Cron only runs jobs on a per minute basis, so to run things every 30 seconds, you can have two jobs, one of which has a 30 second delay. Cron只能按分钟运行作业,所以每30秒运行一次,你可以有两个作业,其中一个有30秒的延迟。 For example: 例如:

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM