Mac 登录后到底自动启动了什么?怎么查出来并关掉?

用终端逐一排查 macOS 在登录时替你启动的东西——登录项、launchd 用户代理与系统守护进程——然后关掉你没同意过的那些。

macOSlaunchctl 服务管理macOS自动化监控启动项应用中风险
先用 osascript 列一遍登录项,再用 launchctl list 列一遍已加载的 launchd 任务。macOS 上会自动启动的东西,几乎都出自这两处。

快速开始

macOS 里能「自动启动」的位置其实有三处:登录项(系统替你重新打开的应用)、launchd 用户代理(你登录后加载的后台任务)、launchd 系统守护进程(开机时、还没人登录就加载的任务)。只有第一处能在「系统设置」里看到,所以「这玩意儿是什么、为什么在跑」在图形界面里才这么难查。这篇文章用终端把三处都读一遍,弄清每个任务到底是什么,再把不该留下的持久关掉——重启也不会复活。

症状

?重启之后,你从没打开过的应用、窗口或菜单栏图标已经在那了。登录后头几分钟机器明显卡顿、风扇狂转。明明卸载过的程序却又冒出来。机器闲置着,电池却一直在掉。

先用 System Events 列一遍所有登录项

这是 macOS 在你登录时替你重新打开的那一类程序,在「系统设置 > 通用 > 登录项」里也能看到。通过 System Events 取到的是一份纯名字列表,方便你复制、与你装过的东西比对、再决定怎么处理。列表里出现你不认识的名字,那就是第一嫌疑人。返回一串名字(或者干脆为空,说明一个登录项都没有),这一步就算成功。

osascript 通过 System Events 列出所有登录时自动启动的应用,并可按名称删除不需要的项。

命令
$ osascript -e 'tell application "System Events" to get the name of every login item'
▾ 撤销
撤销
$ osascript -e 'tell application "System Events" to delete login item "App Name"'

再查 launchd:列出你当前会话里加载的任务

会自动启动的东西并不都是「登录项」。launchd 的用户代理和系统守护进程会悄悄加载,图形界面里根本看不到——只在「系统设置」里查,一定会漏。这份列表给出你会话中每个任务的 PID 和上次退出码:有 PID 说明此刻正在跑,退出码非 0 说明它一直在崩、又被反复拉起。看到一长串任务标签就算成功;重点扫一遍那些第三方前缀(com.google、com.docker 之类的厂商名),确认它们是不是你真想留着的。

用 launchctl list 列出用户域内所有代理的标签、PID 和上次退出状态,排查多余的后台程序。

命令
$ launchctl list | head -30

读懂可疑任务自己的定义文件(plist)

光看任务标签(label)几乎看不出什么,信息全在它的 plist 里:执行的是哪个可执行文件、是加载即运行还是按计划运行、以哪个用户身份运行。把它格式化打印出来,得到的就是一份能直接读的键值表,不用去啃 XML——这样才能分清它是正经的更新器还是你根本不想要的东西。重点看 ProgramArguments(到底执行了什么)和 RunAtLoad / KeepAlive。这一步是可选的:只有当某个标签已经引起你注意时才需要。

把任意属性列表以可读的键值形式输出——不用 Xcode,也不必啃 XML。

命令
$ plutil -p ~/Library/Preferences/com.apple.TextEdit.plist

顺便确认 SSH 远程登录有没有偷偷开着

Mac 上最容易被漏掉的自启项根本不是登录项:只要「远程登录」(SSH)是开的,sshd 从开机那一刻就在监听——没人登录也照跑,而图形界面的启动相关设置里什么都看不到。排查「什么会自动启动」不查这一项就是漏的。这一步要 sudo,因为这是整机级别的设置。看到明确的「Remote Login: On」或「Off」就是查到了;如果显示 On 而你根本没开过,那已经不只是自启烦人,而是安全问题。

用 systemsetup -getremotelogin 查看这台 Mac 是否允许其他机器通过 SSH 连入。

命令
$ sudo systemsetup -getremotelogin

把这个任务持久地关掉

删登录项只能管住应用。如果对方是 launchd 任务,真正管用的办法是写一条 disable 覆盖:launchd 会记住这个任务被关掉了,重启、以及厂商更新 plist 之后都依然生效——而 kill 进程、或者删一个安装程序会重新写回的 plist,都只是暂时的。改完立刻确认新状态,并把对应的 enable 命令记下来,方便反悔。只要任务不再显示为启用、重启后也没复活,这一步就算修好了。

launchctl enable/disable 会写入持久覆盖,使守护进程在重启和 plist 更新后仍保持关闭。

命令
$ sudo launchctl disable system/com.apple.example.daemon
# Confirm current state:
sudo launchctl print-disabled system | grep example
▾ 撤销
撤销
$ sudo launchctl enable system/com.apple.example.daemon

用 launchctl print 确认它的真实状态

新的 print 子命令能一次性读出任务的真实状态——启用还是禁用、上次退出码、PID、启动参数——让你「确认修好了」,而不是「猜修好了」。以后真要主动重启某个任务,也是从这里下手。看到状态是 disabled(或者干脆没有在运行)、上次退出码不再是崩溃—重启的循环,就可以放心了。

现代 launchctl 用法——查看任意 launchd 任务的完整状态,并用真正有效的命令重启。

命令
$ launchctl print gui/$(id -u)/com.apple.Finder
!关错 Apple 的系统守护进程可能弄坏 Wi-Fi、DNS、Time Machine、打印或软件更新。只关你从 plist 里能确认身份的第三方任务,一次只改一个,并把对应的 launchctl enable 命令留在手边。kill 进程不算解决——launchd 会把它重新拉起来。

如何确认已解决

登录项列表里那个名字消失了,launchctl print 显示任务为 disabled,完整重启后没有任何东西复活——进程、菜单栏图标、后台 CPU 占用都没有回来。

一键全部撤销

上面每一条命令都可以撤销。按此顺序执行即可全部还原。

一键全部撤销
$ sudo launchctl enable system/com.apple.example.daemon
osascript -e 'tell application "System Events" to delete login item "App Name"'

执行前请先确认——部分步骤之间可能并非相互独立。

来源

最后验证: 2026-09-21

相关指南