Mac 上的 LaunchAgents 和 LaunchDaemons 是什么,哪些可以删
LaunchAgents 和 LaunchDaemons 是放小 .plist 文件的文件夹,这些文件告诉 macOS 的 launchd 在后台启动什么、什么时候启动。Agent 为某个已登录的用户运行,可以在屏幕上显示东西,Daemon 为整个系统运行,没有界面。已经卸载的 App 留下的第三方项目通常可以删,/System/Library 下的不要碰,移走文件之前先停掉任务。
五个文件夹
Apple 的 launchd 指南 列了这些位置:
| 文件夹 | 里面是什么 | 能不能动 |
|---|---|---|
~/Library/LaunchAgents |
只属于你这个账户的第三方 Agent | 可以,要小心 |
/Library/LaunchAgents |
所有用户共用的第三方 Agent | 可以,要管理员密码 |
/Library/LaunchDaemons |
第三方系统 Daemon | 可以,要管理员密码 |
/System/Library/LaunchAgents |
Apple 的 Agent | 不要动 |
/System/Library/LaunchDaemons |
Apple 的 Daemon | 不要动 |
man launchd 把界线讲得很清楚,Daemon 是全系统一个实例的服务,不应该显示界面,Agent 按用户运行,和用户打交道的事都该放在这里。实际上菜单栏小助手和更新程序多半是 Agent,VPN 服务、音频驱动助手和备份引擎多半是 Daemon。
不是所有后台项目在这里都有文件,App 可以把 plist 放在自己的包里,所以「系统设置 › 通用 › 登录项与扩展」里可能有这些文件夹里找不到的东西,那个页面可以看 怎么阻止 App 开机自启动。
先读一下再判断
ls -la ~/Library/LaunchAgents /Library/LaunchAgents /Library/LaunchDaemons
plutil -p ~/Library/LaunchAgents/com.example.helper.plist
看四个键就能知道大概:
| 键 | 意思 |
|---|---|
Label |
任务的名字,launchctl 用的就是它 |
Program 或 ProgramArguments |
运行什么,要核对的就是这个路径 |
RunAtLoad |
任务一加载就启动,通常是登录或开机时 |
KeepAlive |
进程停了 launchd 会重新拉起来,所以退出它也没用 |
上面的 com.example.helper 只是占位名,换成你自己的文件名。ProgramArguments 指向已经删掉的 App,这个文件就是残留,可以放心移走,指向还在用的 App 的话,移走可能让它的更新、同步、授权、VPN 或者音频出问题。
怎么移除
先停掉任务,只移动文件停不了已经在运行的任务,它会一直加载到注销或重启。
你账户里的 Agent:
launchctl bootout gui/$(id -u)/com.example.helper
mv ~/Library/LaunchAgents/com.example.helper.plist ~/.Trash/
/Library/LaunchDaemons 里的 Daemon:
sudo launchctl bootout system/com.example.helper
sudo mv /Library/LaunchDaemons/com.example.helper.plist ~/.Trash/
/Library/LaunchAgents 里的 Agent 加载在每个用户的会话里,所以用 gui/$(id -u)/ 这种写法停,用 sudo mv 移动文件。这些命令里填的是 Label 的值,它可能和文件名不一样。
用 launchctl print gui/$(id -u)/com.example.helper 或者 sudo launchctl print system/com.example.helper 确认,应该提示找不到这个服务,然后正常用一天,出了问题就把文件放回去再重启。
想留着文件,只是不让任务加载:
launchctl disable gui/$(id -u)/com.example.helper
launchctl print-disabled gui/$(id -u)
同样的目标换成 launchctl enable 就能恢复。
不要这样做
- 不要动
/System/Library/LaunchAgents和/System/Library/LaunchDaemons,它们在只读的系统宗卷上,是 macOS 自己的。 - 不要只看公司名就删,以安全软件或者设备驱动命名的文件,可能就是那个产品工作的方式,公司管理的 Mac 上还可能是公司策略。
- 不要指望删掉还在用的 App 的 plist,只会少一个更新提醒,先看 App 自己有没有这个设置。
- 不要照着老教程用
launchctl unload,Apple 的手册把它列为旧版子命令,现在的写法是bootout。
Mole 能帮什么
Mole 的「软件」里有「启动项」,会列出这些项目,名字读的是每个 plist 自己的 Label,助手程序按所属 App 命名,分成「登录项」「后台服务」等几组,任务指向的东西已经不存在时会标出「程序缺失」,这通常就是残留。~/Library/LaunchAgents、/Library/LaunchAgents 和 /Library/LaunchDaemons 下通过校验的 launchd plist,可以用这一行的开关停用、再启用,也可以移到废纸篓,Mole 会先停掉任务。安全和设备管理产品保持锁定,改不了的项目会打开系统设置。「状态」里有不认识的进程时,「为什么在运行?」会列出它的 launchd 服务和 plist。通过 Mole 卸载 App 时,它的启动项也会列出来让你确认。
常见问题
LaunchAgents 里的文件可以删吗?
已卸载 App 的残留可以,还在用的 App 就不一定了。先用 plutil -p 看 ProgramArguments,再用 launchctl bootout 停掉任务,把文件移到废纸篓,需要时还能放回去。
LaunchAgent 和 LaunchDaemon 有什么区别?
Agent 为每个已登录的用户运行,可以和用户交互,Daemon 全系统只有一个实例,通常在有人登录之前就启动了,没有界面。
删掉的 LaunchAgent 为什么又回来了?
装它的 App 还在,下次打开或者更新时又写了一份,到 App 里关掉这个功能,或者卸载 App,只删文件是留不住的。
LaunchAgent 可能是恶意软件吗?
可能,流氓软件常常装在这里,因为重启后还能继续运行。不认识的 Label 如果运行的是隐藏文件夹或者临时路径里的东西,值得仔细看看,搜一下确切路径,再查程序是谁签名的。
移除之后需要重启吗?
用了 launchctl bootout 就不需要,它会立刻停掉。只移动了文件的话,任务会一直加载到注销或重启。