一位朋友最近在服务器上装了几个 LLM 相关工具,装完发现账号被打开了 linger——他自己从没手动开过。翻一下 /var/lib/systemd/linger 就能确认,这个开关确实是开着的。
大概率是某个安装脚本自作主张:以为不开 linger,nohup 起的进程就保不住,于是顺手把这个系统级开关按了下去。问题是,这个假设本身就是错的——至少在接近默认配置的 Debian 上,linger 跟“注销后进程死不死”没什么关系。
速览:两个开关,管的是两件事
近几年的 Debian 默认不会在你注销时杀掉后台进程,screen、tmux、nohup 留下的进程可以照常挂着。管这件事的开关叫 KillUserProcesses,写在 /etc/systemd/logind.conf 里,默认关闭。
linger 管的是另一件事:允许你的用户管理器(user@.service)在登录之前就启动,并且在你最后一次注销之后继续留着,不会因为没人登录就被系统回收。前者决定注销那一刻要不要清场,后者决定用户级服务能不能提前起、能不能一直留。两件事经常被当成同一件事,其实是两条线。
| 开关 | 默认状态(Debian) | 管什么 | 查询命令 | 关闭命令 |
|---|---|---|---|---|
| KillUserProcesses | 关闭 | 注销时是否清掉用户进程 | 看 /etc/systemd/logind.conf | 改配置文件,重启 systemd-logind |
| linger | 关闭(需手动开) | 用户管理器能否登录前启动、注销后是否留存 | loginctl show-user 用户名 -p Linger | loginctl disable-linger |
这套判断建立在“接近默认配置的 Debian”上。不同发行版、不同 systemd 版本,KillUserProcesses 的默认值和 linger 的具体行为都可能有出入,不能直接套到所有系统上。
现场:一个疑似被脚本悄悄按下的开关
这件事本身没有被坐实。作者只是在朋友账号上看到了异常的 linger 状态,没有脚本源码或日志能证明是哪个安装程序干的,只能算一个合理推测。
顺着这个推测往下看,真正值得警惕的是查询和关闭都太不透明。查自己账号有没有开,用 loginctl show-user 用户名 -p Linger 就能看到 yes/no;查不到工具的人,翻 /var/lib/systemd/linger 目录里有没有对应文件也行。想关掉,自己账号用 loginctl disable-linger,root 在后面加用户名可以代管别人的账号。
linger 打开确实有实际用处。作者测试新的 SELinux 策略要频繁重启笔记本,开了 linger 之后,Wi-Fi、PipeWire、蓝牙这些用户上下文服务能在登录前就先启动,即便图形登录界面出了问题,也能直接 ssh 进去。这类好处取决于你到底跑了哪些用户级服务,不是开了 linger 就自动拿到,具体系统上体验可能完全不一样。
谁该做什么
Debian/systemd 管理员和 Linux 高级用户:批量跑一遍 loginctl show-user 用户名 -p Linger,检查团队服务器上有没有意外开启的账号,尤其是装过第三方 LLM 工具或一键安装脚本的机器。发现异常就用 disable-linger 关掉,再回头查是哪个脚本干的,别等下次重启才发现服务提前跑了起来。
编写安装脚本和用户级服务的开发者:别拿“不开 linger,nohup 就保不住”当理由去动这个开关,这个假设本身就站不住脚。如果确实需要用户级服务提前启动,先给用户一个明确提示或参数确认,不要默认帮别人按下系统级开关。
锐评
真正该较真的不是 linger 好不好用,它对特定场景确实方便。该较真的是查询接口太弱,导致大多数人根本不知道自己账号被谁动过手脚。
己所不欲,勿施于人——安装脚本连这点基本的克制都没有,替用户按下一个连查询都不方便的系统开关,还美其名曰图省事。这类“我猜你需要,所以我帮你办了”的脚本不是第一次这么干:装开发工具塞 PATH,装 Docker 塞用户组,这次轮到 linger,只是换了一个更隐蔽的开关,把用户级服务的启动边界从“登录之后”悄悄挪到了“开机就跑”。
