Mac Launchd 启动任务

先分别介绍一下我了解到 Mac 设置启动任务的方式:

1、进入系统偏好「设置」->「帐户」->「登陆项」
操作很简单,直接拖任务进去也可以,或点击底部的+号添加即可。

2、利用/System/Library/StartupItems/Library/StartupItems/配置文件
在这两个对应目录下,可以添加以下两种内容:可执行程序和StartupParameters.plist文件(需要有权限)。

3、利用 Launchd 系统初始化进程配置
LaunchdMac下用于初始化操作系统的关键进程。通过启动硬盘指定目录下的配置文件,来完成启动任务。这些文件为plist,本质上是XML

Launchd 目录配置

MacLaunchdplist文件放置的目录有:

~/Library/LaunchAgents 由用户自己定义的任务项
/Library/LaunchAgents 由管理员为用户定义的任务项
/Library/LaunchDaemons 由管理员定义的守护进程任务项
/System/Library/LaunchAgents 由Mac OS X为用户定义的任务项
/System/Library/LaunchDaemons 由Mac OS X定义的守护进程任务项

我们新写的建议放在~/Library/LaunchAgents下面。

下面再来理解几个基础概念:

/System/Library和/Library和~/Library目录的区别?

/System/Library 目录是存放Apple自己开发的软件。
/Library 目录是系统管理员存放的第三方软件。
~/Library/ 是用户自己存放的第三方软件。

LaunchDaemons和LaunchAgents的区别?

LaunchDaemons 是用户未登陆前就启动的服务(守护进程)。
LaunchAgents 是用户登陆后启动的服务(守护进程)。

Launchd plist 配置

这里列举几个比较有用的配置关键字:

标签 必填 说明
Label 标识符,用来表示该任务的唯一性
Program 程序名称,用来说明运行哪个程序、脚本
ProgramArguments 同上,与Program二选一或一起使用,只是可以运行多个程序、可带参数
WatchPaths监控路径,当路径文件有变化是运行程序,也是数组
RunAtLoad 是否在加载的同时启动
StartCalendarInterval 运行的时间,单个时间点使用dict,多个时间点使用 array -> dict
StartInterval 时间间隔,与StartCalendarInterval使用其一,单位为秒
StandardInPath、StandardOutPath、StandardErrorPath 标准的输入输出错误文件,这里建议不要使用.log作为后缀,会打不开里面的信息

Launchd 使用案例

两种指定要执行命令的方法:

  • 使用Program和ProgramArguments

Program, 运行命令或要执行文件路径
ProgramArguments, 执行时传入参数

  • 只使用ProgramArguments

此时,ProgramArguments的每个参数为要执行的命令或文件路径,其它参数为传入参数

两种设置执行时间的方法:

  • StartCalendarInterval

使用元素Minute, Hour, Day, Month, Weekday指定执行时间,如:

<!-- 每天的9:30执行 -->
<key>StartCalendarInterval</key>
<dict>
  <key>Minute</key>
  <integer>30</integer>
  <key>Hour</key>
  <integer>9</integer>
</dict>
  • StartInterval

设置执行的时间间隔,单位为秒,如:

<!-- 每小时执行一次 -->
<key>StartInterval</key>
<integer>3600</integer>

Launchd 定时任务

1.编写shell脚本文件

这里我们在~/Library/LaunchAgents下新建一个文件test.sh文件,写入要执行的内容,比如:

#!/bin/bash
say hello world
echo "out: 茶豆网:https://chadou.me"

上面的脚本会让电脑发声“hello world”,记得打开电脑音量哟!

注意:
你需要将test.sh修改为可执行文件,否则,脚本无法执行。执行命令并查看test.sh是否可执行(拥有3个x权限),如下:

$ chmod a+x test.sh
$ ls -l
-rwxr-xr-x   1 david  staff    86  1 31 17:10 test.sh

2.编写plist文件

这里我们在~/Library/LaunchAgents下新建一个me.chadou.test.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>me.chadou.test</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/david/Library/LaunchAgents/test.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

然后,使用plutil命令来验证plist的格式是否正确(无法验证命令有效性),如下:

$ plutil -lint me.chadou.test.plist
me.chadou.test.plist: OK

3.加载命令

使用launchctl命令加载plist文件,launchctl是一个统一的服务管理框架,启动、停止和管理守护进程、应用程序、进程和脚本。具体参数如下:

# 加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上
$ launchctl load -w me.chadou.test.plist
$ launchctl start me.chadou.test.plist

# 删除任务
$ launchctl stop me.chadou.test.plist
$ launchctl unload -w me.chadou.test.plist

# 查看任务列表, 使用 grep '任务部分名字' 过滤
$ launchctl list | grep 'me.chadou.test'

其他说明:

  • 如果执行launchctl load命令出现me.chadou.test.plist: Path had bad ownership/permissions,需要为plist文件赋予600权限,执行下面命令:
sudo chmod 600 me.chadou.test.plist
  • 如何执行launchctl list命令出现错误的代码,则需要仔细检查shell脚本内容。
$ launchctl list | grep 'me.chadou.test'
-    78    com.applefs.user # 错误结果
-    0     com.applefs.user # 正确结果
  • shell脚本输出如果有中文,中文部分乱码,则需要在shell脚本中指定编码,如下:
#!/bin/bash

LANG=en_US.UTF-8
export LANG

echo "out: 茶豆网:https://chadou.me"

如需转载,请注明出处: https://www.chadou.me/p/234

最新发布