macOS 下的 systemd —— launchd
2023-12-11 tech mac systemd launchd 8 mins 1 图 3003 字
背景
在 macOS 中,Launchd 是一个系统级别的进程管理工具,用于启动、停止和管理系统和用户级别的进程。Launchd 进程本身是由内核启动的,并负责启动其他进程,包括系统服务和用户级别的进程。
Launchd 启动的进程通常会将输出日志写入系统日志,我们可以使用 macOS 提供的 Console 应用程序来查看这些日志。
编写 launchd 配置文件
launchd
的配置文件是通过一个 plist
文件来定义的(plist
是 property list
的缩写),一个典型的格式如下:
<?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>
<!-- Label 可以看作是守护进程的名称,key 是配置的名称,key 的下一行就是它的值,string 标签表示值的类型是字符串 -->
<key>Label</key>
<string>com.example.app</string>
<key>Program</key>
<string>/Users/Me/Scripts/cleanup.sh</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
说明:
- 配置文件中,除了
dict
里面的那一部分,其他的都是固定的,不需要修改。 - 三个字段说明:
Label
:也就是服务的名字,可以随便取,但是不能重复。我们通过launchctl list
来查看的时候,列出的就是这个名字。上述例子是com.example.app
。Program
:要启动的程序的路径,需要填写绝对路径。上述例子是/Users/Me/Scripts/cleanup.sh
。如果需要加参数的话,需要使用ProgramArguments
来代替Program
。RunAtLoad
:是否在配置被加载的时候就运行,默认是false
,如果需要在启动的时候就运行,需要设置为true
。上述例子是true
。- 标签说明:
key
就是属性的名称,紧跟着key
的下一行就是属性的值,属性的值的类型通过其标签反映出来,比如上面的<string>
表示包裹的是一个字符串类型,而<true/>
表示是一个布尔类型,而且它的值是true
。
mac 中很多配置都是通过
plist
来定义的,
macOS 中有两种类型的守护进程,一种是系统级别的(Daemons
),一种是用户级别的(Agents
),它们的配置文件放的位置是不一样的。
下面是 launchd
配置文件的路径:
~/Library/LaunchAgents
:用户级别的守护进程配置文件路径。这里保存特定用户的Agents
配置。(一般情况都是放这里)/Library/LaunchAgents
:用户级别的守护进程配置文件路径。这里保存所有用户共用的Agents
配置。/Library/LaunchDaemons
:全局的Daemons
配置。/System/Library/LaunchAgents
:所有登录用户共用的Agents
配置。/System/Library/LaunchDaemons
:全局的Daemons
配置。
常用命令
列出所有 launchd 管理的服务
launchctl list
- 第一列是进程
id
,如果是0
说明没有在运行状态。 - 第二列的
0
表示的是进程上一次的退出状态码,0
一般表示成功。 - 第三列表示的是我们在
plist
配置文件中配置的Label
的值。
开机启动/不启动
launchctl load ~/Library/LaunchAgents/com.example.app.plist
launchctl unload ~/Library/LaunchAgents/com.example.app.plist
相当于systemctl enable xxx
、systemctl disable xxx
启动/停止
launchctl start com.example.app
launchctl stop com.example.app
相当于 systemctl start xxx
、 systemctl stop xxx
案例frps
文件 ~/Library/LaunchAgents/frpc.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>KeepAlive</key>
<true/>
<key>Label</key>
<string>frpc</string>
<key>ProgramArguments</key>
<array>
<string>/Users/kelu/Workspace/bin/frp_0.52.3_darwin_arm64/frpc</string>
<string>-c</string>
<string>/Users/kelu/Workspace/bin/frp_0.52.3_darwin_arm64/tmp.toml</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
KeepAlive,指定后台保持运行
这个配置文件的作用是,以守护进程的方式来启动命令。
launchctl load ~/Library/LaunchAgents/frpc.plist
确认已经运行
ps aux | grep frpc
查看日志,目前我用 console 查不出来 frpc 的日志,先放着了。
某些网络会对长时间的udp连接做重置,所以我们本地耶可以设置定时任务杀掉frpc。