Mac launchctl 自定义服务启动

原文:https://ichochy.com/posts/20231128.html


launchd

launchd – 系统范围内的守护进程(LaunchDaemons)/代理程序(LaunchAgents)的主程序 在启动过程中,内核调用 launchd 作为第一个进程运行,并进一步引导系统的其余部分。

守护进程和服务启动图例

守护进程和服务由 launchd 在两个单独的会话上下文中启动

根据定义,守护进程是系统范围的服务,其中所有客户端都有一个实例。 代理是一种服务,以每个用户为基础运行。
守护进程不应尝试显示 UI 或直接与用户的登录会话交互。 所有涉及与用户交互地应通过代理服务完成,如:运行程序,显示 UI

路径说明

路径 加载 说明
/System/Library/LaunchDaemons 系统启动 提供系统范围的守护进程(Apple)
/System/Library/LaunchAgents 系统启动 提供系统范围的用户代理(Apple)
/Library/LaunchDaemons 用户登录 提供所有用户的守护进程
/Library/LaunchAgents 用户登录 提供所有用户的代理进程
~/Library/LaunchAgents 用户登录 提供当前用户的代理进程

更多具体信息查看系统帮助文档:launchd

launchd.plist

launchd.plist – 系统范围内的守护进程(LaunchDaemons)/代理程序(LaunchAgents)的配置文件

可以使用 launchctl 加载到 launchd 的列表,并根据配置文件的具体参数属性进行配置加载运行。

配置文件的命名

文件命名为 <Label>.plist。 因此,如果您的工作标签(Label)是 com.ichochy.test,您的 plist 文件应命名为:com.ichochy.test.plist

参数属性

  • Label
    • 作业进程的唯一标识,是必要参数
  • Program
    • 作业进程的执行绝对路径
    • Program存在时,将替代ProgramArguments的第一个参数
    • Program不存在时,将由ProgramArguments的第一个参数替代
  • ProgramArguments
    • 作业进程的执行参数
    • Program不存在时,将由ProgramArguments的第一个参数作为作业进程的执行绝对路径
  • KeepAlive
    • 作业进程是否保留运行
    • false为默认值,停止后不再保留运行
    • true,停止后再次启动运行
    • SuccessfulExit
    • NetworkState
    • PathState
    • Crashed
  • RunAtLoad
    • false为默认值,启动加载时不启动运行
    • true,启动加载时启动运行
  • WorkingDirectory
    • 工作目录
  • EnvironmentVariables
    • 配置环境变量
  • TimeOut
    • 启动超时时间
  • ExitTimeOut
    • 退出超时时间
  • ThrottleInterval
    • 间歇时间
  • StartInterval
    • 间隔启动时间,单位为秒
  • StartCalendarInterval
    • 间隔启动时间,单位可以指定日期
    • Minute
      • 分钟 0-59
    • Hour
      • 小时 0-23
    • Day
      • 天 1-31
    • Weekday
      • 工作日 0-7
    • Month
      • 月 1-12
    • StandardInPath
      • stdin 输入信息的日志路径
    • StandardOutPath
      • stdout 输出信息的日志路径
    • StandardErrorPath
      • stderr 错误输出信息的日志路径
    • ProcessType
      • 进程类型,根据作业类型限制应用资源
      • Background
      • Standard
      • Adaptive
      • Interactive

plist 实例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
        "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.ichochy.exampled</string>
        <key>Program</key>
        <string>/path/tp/exampled</string>
        <key>ProgramArguments</key>
        <array>
            <string>exampled</string>
            <string>argv1</string>
            <string>argv2</string>
        </array>
        <key>MachServices</key>
        <dict>
            <key>com.ichochy.exampled</key>
            <true/>
        </dict>
    </dict>
</plist>

“Hello World!” launchd Job

<?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.ichochy.hello</string>
        <key>ProgramArguments</key>
        <array>
            <string>hello</string>
            <string>world</string>
        </array>
        <key>KeepAlive</key>
        <true/>
    </dict>
</plist>

Debugging launchd Jobs

<?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.ichochy.sleep</string>
        <key>ProgramArguments</key>
        <array>
            <string>sleep</string>
            <string>100</string>
        </array>
        <key>StandardOutPath</key>
        <string>/var/log/myjob.log</string>
        <key>StandardErrorPath</key>
        <string>/var/log/myjob.log</string>
        <key>Debug</key>
        <true/>
        <key>SoftResourceLimits</key>
        <dict>
            <key>Core</key>
            <integer>9223372036854775807</integer>
        </dict>
        <key>HardResourceLimits</key>
        <dict>
            <key>Core</key>
            <integer>9223372036854775807</integer>
        </dict>
    </dict>
</plist>

Running a Job Periodically

<?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.ichochy.touchsomefile</string>
        <key>ProgramArguments</key>
        <array>
            <string>touch</string>
            <string>/tmp/helloworld</string>
        </array>
        <key>StartInterval</key>
        <integer>300</integer>
    </dict>
</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>com.ichochy.touchsomefile</string>
        <key>ProgramArguments</key>
        <array>
            <string>touch</string>
            <string>/tmp/helloworld</string>
        </array>
        <key>StartCalendarInterval</key>
        <dict>
            <key>Minute</key>
            <integer>45</integer>
            <key>Hour</key>
            <integer>13</integer>
            <key>Day</key>
            <integer>7</integer>
        </dict>
    </dict>
</plist>

Monitoring a Directory

<?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.ichochy.watchhostconfig</string>
        <key>ProgramArguments</key>
        <array>
            <string>syslog</string>
            <string>-s</string>
            <string>-l</string>
            <string>notice</string>
            <string>somebody touched /etc/hostconfig</string>
        </array>
        <key>WatchPaths</key>
        <array>
            <string>/etc/hostconfig</string>
        </array>
    </dict>
</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>com.ichochy.mailpush</string>
        <key>ProgramArguments</key>
        <array>
            <string>my_custom_mail_push_tool</string>
        </array>
        <key>QueueDirectories</key>
        <array>
            <string>/var/spool/mymailqdir</string>
        </array>
    </dict>
</plist>

更多具体信息查看系统帮助文档:launchd.plist

launchctl

launchctllaunchd 的管理工具
通过 launchctl 交互来管理和检查 launchd 守护进程、代理进程和 XPC 服务。

命令执行

  launchctl subcommand [arguments ...]

展示加载列表

launchctl list

基本操作

# enable | disable 
launchctl enable  com.ichochy.example.plist      #启用 plist
launchctl disable  com.ichochy.example.plist     #禁用 plist
# load | unload 
launchctl load  com.ichochy.example.plist        #加载 plist
launchctl unload  com.ichochy.example.plist      #卸载 plist
#加载/卸载 plist,
# 参数 w 覆盖操作
# 参数 F 强制操作
launchctl load/unload [-wF] plist  
launchctl remove  com.ichochy.example      #删除 plist
launchctl start  com.ichochy.example       #启动 plist
launchctl stop  com.ichochy.example        #停止 plist

更多具体信息查看系统帮助文档:launchctl

参考引用

launchd
launchd.plist
launchctl
https://developer.apple.com/
https://www.launchd.info/

posted @ 2023-12-05 11:17  iChochy  阅读(757)  评论(0编辑  收藏  举报