惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
博客园_首页
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
The Cloudflare Blog
罗磊的独立博客
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
博客园 - 叶小钗
The GitHub Blog
The GitHub Blog
Last Week in AI
Last Week in AI
J
Java Code Geeks
MyScale Blog
MyScale Blog
G
Google Developers Blog
U
Unit 42
Y
Y Combinator Blog
P
Proofpoint News Feed
Vercel News
Vercel News

回忆中的明天

自己写一个Web 端的MiMo TTS Chat,方便实现文本转语音,API限免中 · 回忆中的明天 NVIDIA NIM 开发平台,提供超多免费大模型 · 回忆中的明天 iTranslation 简单快捷的翻译软件,支持数十种语言互译 · 回忆中的明天 国内外免费大模型平台,支持 API 调用的超多免费大模型 · 回忆中的明天 SiliconFlow 硅基流动一站式大模型云服务平台,提供超多免费大模型 · 回忆中的明天 Xiaomi MiMo 小米大模型团队开发的大语言模型,开源限免中…… · 回忆中的明天 BigModel 智谱大模型开放平台,提供超多自研免费大模型 · 回忆中的明天 OpenRouter 模型聚合平台,提供超多免费模型使用 · 回忆中的明天 iReader 英语点读学习系统,译林小学英语在线点读 · 回忆中的明天 ZenMux 企业级大模型聚合平台,提供免费试用模型 Gemini 3 Pro · 回忆中的明天 英语学习,新概念英语在线点读、全文朗读学习系统 · 回忆中的明天 iGSTT(Gemini STT) 开源免费的语音转文本(STT)的命令行工具 · 回忆中的明天 Python 项目打包,并上传到 PyPI,分享项目 · 回忆中的明天 iGTTS(Gemini TTS) 开源免费的文本转语音(TTS)的命令行工具 · 回忆中的明天 iChat(AI Chat) 智能聊天工具,支持 MiMo、DeepSeek、Gemini、Grok、OpenAI和自定义AI · 回忆中的明天 NanoPi R2S 安装 Debian 固件系统,旁路由网络代理内网转发,决解直连网络卡顿 nftables · 回忆中的明天 NanoPi R2S Armbian Linux 旁路由网络代理内网转发,决解直连网络卡顿 iptables · 回忆中的明天 sing-box rule-set · 回忆中的明天 Xcode 最全最实用的快捷键列表 · 回忆中的明天 SwiftUI 中的@State、@Bindable和@Binding · 回忆中的明天 免费的图床服务器-GitHub Pages · 回忆中的明天 A Free Native Image Uploading Tool for macOS · 回忆中的明天 免费的图床服务器-Cloudflare-R2 · 回忆中的明天 图传 (iUploader) - macOS 免费原生图床上传利器 · 回忆中的明天 本地无法加载托管到Cloudflare中的图片等资源,权限错误403 · 回忆中的明天 国内、外免费公共的DNS,支持的DoH,防止污染、篡改的问题 · 回忆中的明天 macOS 系统下载和安装 · 回忆中的明天 使用 CURL 命令调试和诊断网络问题,网站请求测速 · 回忆中的明天 WARP Beta for macOS 支持新协议 MASQUE · 回忆中的明天 2024年自用国外靠谱的 VPS 服务器推荐 · 回忆中的明天
Mac launchctl 自定义服务启动 · 回忆中的明天
2023-11-28 · via 回忆中的明天

原文:https://ichochy.com/posts/mac/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 <string>
    - 作业进程的唯一标识,是必要参数
- Program <string>
    - 作业执行的命令
- ProgramArguments <array of strings>
    - 作业执行的参数
    - 第一个参数为作业执行的命令,`Program`存在时,将由`Program`替代
    - 从第二个参数开始为执行的参数
- KeepAlive <boolean or dictionary of stuff>
    - 作业进程是否保留运行
    - `false`为默认值,停止后不再保留运行
    - `true`,停止后再次启动运行
    - SuccessfulExit <boolean>
    - NetworkState <boolean>
    - PathState <dictionary of booleans>
    - Crashed <boolean>
- RunAtLoad <boolean>
    - `false`为默认值,启动加载时不启动运行
    - `true`,启动加载时启动运行
- WorkingDirectory <string>
    - 工作目录
- EnvironmentVariables <dictionary of strings>
    - 配置环境变量
- TimeOut <integer>
    - 启动超时时间
- ExitTimeOut <integer>
    - 退出超时时间
- ThrottleInterval <integer>
    - 间歇时间
- StartInterval <integer>
    - 间隔启动时间,单位为秒
- StartCalendarInterval <dictionary of integers or array of dictionaries of
  integers>
    - 间隔启动时间,单位可以指定日期
    - Minute <integer>
        - 分钟 0-59
    - Hour <integer>
        - 小时 0-23
    - Day <integer>
        - 天 1-31
    - Weekday <integer>
        - 工作日 0-7
    - Month <integer>
        - 月 1-12
    - StandardInPath <string>
        - stdin 输入信息的日志路径
    - StandardOutPath <string>
        - stdout 输出信息的日志路径
    - StandardErrorPath <string>
        - stderr 错误输出信息的日志路径
    - ProcessType <string>
        - 进程类型,根据作业类型限制应用资源
        - 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.example</string>
        <key>Program</key>
        <string>/path/tp/example</string>
        <key>ProgramArguments</key>
        <array>
            <string>example</string>
            <string>argv1</string>
            <string>argv2</string>
        </array>
        <key>MachServices</key>
        <dict>
            <key>com.ichochy.example</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 ...]

显示加载列表

基本操作

# 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  
# start | stop | remove
launchctl start  com.ichochy.example       #启动 plist
launchctl stop  com.ichochy.example        #停止 plist
launchctl remove  com.ichochy.example      #删除 plist

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

查看日志

launchctl操作时,出现错误后,可以查看launchd日志,了解具体的错误信息

命令查看launchd日志

tail -f /private/var/log/com.apple.xpc.launchd/launchd.log

控制台应用查看launchd日志

  • 应用程序中的实用工具中找到控制台,并打开
  • 切换到日志报告,找到launchd.log,并打开,就可以查看launchd日志

参考引用

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