相关目录
- /System/Library/LaunchDaemons 操作系统,用户登录前生效,以 root 身份执行任务
- /System/Library/LaunchAgents 操作系统,用户登录后生效,以 root 身份执行任务
- /Library/LaunchDaemons 系统管理员,用户登录前生效,以 root 身份执行任务
- /Library/LaunchAgents 系统管理员,用户登录后生效,以 root 身份执行任务
- ~/Library/LaunchAgents 当前用户,用户登录后生效,以当前登录用户身份执行任务
使任务生效
- 将 plist 文件按需要放置在上文的相关目录中
- launchctl load <plist path>
执行上述操作后任务会立即生效,且重启系统后也会自动生效。如果 plist 没有放在指定的目录,重启系统后不会再生效。
如果 plist 存在 Key Disabled,且其值为 true,launchctl load 会提示 nothing found to load,系统启动时也不会自动生效人物,如果要手动强制启动,忽略 Disabled 为 true 带来的影响,传递 -wF 参数给 launchctl 即可。
使任务失效
- launchctl unload <plist path>
- 将相关 plist 文件从原有目录中移除
执行上述操作后,任务会立即失效,plist 文件不会被移除,但是如果不将其从相关目录移走的话,重启系统后任务仍然会自动生效。
plist 文件范例
<?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>name.zhengwei.test</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Wayne/Desktop/test.sh</string>
</array>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>10</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/test.err</string>
<key>StandardOutPath</key>
<string>/tmp/test.out</string>
</dict>
</plist>
- XML 节点层级为 plist > dict > key / value
- key /value 以节点的形式交替出现,value 支持的数据格式有 integer、string、array、true、false 等等
- Label、Program和ProgramArguments 三个 Key 必须存在
- Program 为要启动的应用程序或脚本路径
- ProgramArguments 为传给依次传给 Program 的参数集合
参考链接
2012.03.08更新:
以root身份运行
在设置nginx时候发现一直无法绑定80端口,反复尝试后发现以root身份运行job和plist放在哪层的LaunchAgents or LaunchDeamons无关,关键在于如果手动load plist的时候必须用sudo。另外,如果要sudo launchctl load 的话,plist文件的ownership要是root,否则是有一个消息提示:Dobious ownership on file…
要随机启动必须放在/System/Library/LaunchDaemons或/Library/LaunchDaemons之下,原因是因为LaunchAgents下的plist都会以当前登录用户的身份load进来……
总结出来就是,如果你的job需要以root身份运行饼随机启动,只要将它的plist文件放置在上述的任意LaunchDaemons目录下,并指定其ownership为root后通过sudo launchctl load <plist-file>即可。
参考:
Daemon的反复启动问题
设定nginx登录后自启动后发现,由于缺省情况下是生成子进程后父进程立即退出,导致launchctl在KeepAlive配置的作用下反复启动nginx,产生了很多错误信息,所以在设置守护进程的时候要注意规避这类问题,nginx可以通过设置daemon off;或者去除掉KeepAlive设置来解决。