bash 在没有 root 权限的情况下,在 Mac OS X 上定期运行 shell 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23872734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run a shell script periodically on Mac OS X without root permission
提问by user3671325
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 的文件,我在谷歌搜索,发现 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
命令执行时没有任何错误,但我在 work.txt 中没有看到任何内容
can anyone help me please ?
有人可以帮我吗?
采纳答案by ghoti
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.The crontab -
command should be used with caution, as a short-cut.
请注意,此命令还将替换您已有的任何 crontab。该crontab -
命令应谨慎使用,作为捷径。
If you want to edit an existing crontab, so as to avoid obliterating previously set jobs, you can use crontab -e
. (If it launches vim
and you don't know how to use vim
, you can exit by hitting ESC:q!Enterand then go find editor documentation.)
如果要编辑现有的 crontab,以避免删除之前设置的作业,可以使用crontab -e
. (如果它启动vim
并且您不知道如何使用vim
,您可以通过点击退出ESC:q!Enter然后去查找编辑器文档。)
If you want instructions on how to edit crontabs, type man crontab
at your shell. If you want syntax information on the crontab file, man 5 crontab
will show you that.
如果您需要有关如何编辑 crontab 的说明,请man crontab
在您的 shell 中键入。如果您想要有关 crontab 文件的语法信息,man 5 crontab
将显示给您。
Enjoy!
享受!
UPDATE:(per comments)
更新:(根据评论)
To run your job every 30 seconds requires a simple hack. 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. For example:
每 30 秒运行一次你的工作需要一个简单的技巧。Cron 仅以每分钟为基础运行作业,因此要每 30 秒运行一次,您可以有两个作业,其中一个有 30 秒的延迟。例如:
#Mn Hr Da Mo DW Command
* * * * * /Users/paul/Desktop/1.sh
* * * * * sleep 30; /Users/paul/Desktop/1.sh
Hope this helps.
希望这可以帮助。
回答by mklement0
To clarify: The OP's .plist
file itselfwas perfectly OK- the problem turned out to be insidethe 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 preferredway of scheduling (recurring) tasks(see below for more).
在 OS X 上,使用.plist
由 CLI 加载并由launchctl
守护程序管理器调用的文件launchd
是调度(重复)任务的首选方式(更多信息见下文)。
Things to note:
注意事项:
- The format of
launchd
.plist
filesis described inman launchd.plist
- For a
.plist
file to be loaded every time the currentuser logs in, it must be placed in~/Library/LaunchAgents/
(all-usersfiles must be placed in/Library/LaunchAgent/
- requires root privileges). - Specifying output-capture fileswith keys
StandardOutPath
andStandardErrorPath
means that successive invocations appendto the files specified, which means that these files keep growing indefinitely, unless managed externally. - Re troubleshooting: @Grady Player's advice applies: launch
Console.app
and look forcom.apple.launchd.peruser
entries - a failure to invoke the command specified in the.plist
would show there.
- 该格式
launchd
.plist
的文件中描述man launchd.plist
- 对于
.plist
每次当前用户登录时要加载的文件,必须将其放入~/Library/LaunchAgents/
(必须放入所有用户文件/Library/LaunchAgent/
- 需要 root 权限)。 - 指定输出捕获文件的钥匙
StandardOutPath
,并StandardErrorPath
意味着后续调用追加到指定的文件,这意味着这些文件保持无限增长,除非外部管理。 - 重新故障排除:@Grady Player 的建议适用:启动
Console.app
并查找com.apple.launchd.peruser
条目 - 调用中指定的命令失败.plist
将显示在那里。
@ghoti's answerdescribes a general Unix alternativeto launchd
, cron
(typically used on Linux):
@ ghoti的答案描述了一般的Unix的替代来launchd
,cron
(通常在Linux上使用):
As for how cron
relates to OS X: @ghoti asks:
至于cron
与 OS X 的关系:@goti 问:
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. See launchctl(1) for more information.
尽管达尔文 [OS X] 正式支持 cron(8) 和 crontab(5),但它们的功能已被吸收到 launchd(8) 中,它提供了一种更灵活的自动执行命令的方式。有关详细信息,请参阅 launchctl(1)。
The bottom lineis this:
的底线是这样的:
- If you come from a *nix background, you may be more comfortable with continuing to use
cron
andcrontab
, assuming:- you're aware of the fact that additional background tasks, scheduled via
launchd
, may exist. - you're aware of
cron
's limitations and can work with/around them.
- you're aware of the fact that additional background tasks, scheduled via
- 如果您来自 *nix 背景,您可能更愿意继续使用
cron
andcrontab
,假设:- 您知道
launchd
可能存在通过 安排的其他后台任务。 - 您知道
cron
的限制并且可以使用/解决它们。
- 您知道
- Otherwise, on 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). - 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 bylaunchd
.
- many third-party apps use the native
- 否则,在 OS X 上:
- 许多第三方应用程序使用本机
launchd
功能,因此通过(对于所有用户)或(对于当前用户)中的.plist
文件指定定期后台任务。/Library/LaunchAgents
~/Library/LaunchAgents
- 如果你想集中的后台任务管理,这些位置和/或要采取的增加灵活性的优势
launchd
提供,请通过指定后台任务.plist
的评估文件launchd
。
- 许多第三方应用程序使用本机
Adding simplecron
tasks is probably simpler than creating .plist
files for launchd
, but 3rd-party utilities such as Lingon 3can help with the latter.
添加简单cron
任务可能比为 创建.plist
文件更简单launchd
,但 3rd-party 实用程序(例如Lingon 3)可以帮助后者。
Also, there are subtle differencesin 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 30seconds:
launchd
举个例子,增加了灵活性:OP,在后续评论中,要求任务每30秒运行一次:
The minimum interval for
cron
tasks is 60 seconds, necessitating the workaround in @ghoti's answer.By contrast, with the
launchd
.plist
file, changing<key>StartInterval</key><integer>60</integer>
to<key>StartInterval</key><integer>30</integer>
is enough.
任务的最小间隔为
cron
60 秒,需要在@ghti 的回答中解决。相比之下,与
launchd
.plist
文件,改变<key>StartInterval</key><integer>60</integer>
以<key>StartInterval</key><integer>30</integer>
就够了。