Linux强制踢出用户需避免误杀自身:root通过SSH执行pkill -u root会断开当前连接;安全做法是本地tty登录后用pkill -KILL -t逐个终止其他TTY,或用loginctl terminate-user仅对非root用户生效。

不能直接“强制所有用户下线”而不影响自己——root 用户若通过 SSH 登录,执行该操作会连带踢掉自己,导致连接中断甚至无法恢复。 真正可行的是:以本地 console(如 tty1)登录 root 账户后,再批量终止其他远程会话;或保留当前会话、仅踢出其余所有用户。
pkill -u 会误杀 root 自身进程
执行 pkill -u root 或 pkill -9 -u root 时,只要当前 shell 是 root 启动的(绝大多数 SSH 登录都是),该命令就会命中自己的 sshd 和 bash 进程,终端立即断开。这不是 bug,是信号匹配逻辑的必然结果。
- 只对非 root 用户生效:例如
pkill -9 -u alice安全,不会波及当前会话 - 想清空所有普通用户?先用
w确认哪些用户不是 root,再逐个或用循环处理 - 别依赖
who | awk '{print $1}' | sort -u直接喂给 pkill —— 它会把 root 也列进去
loginctl terminate-user 不适用于 root
loginctl terminate-user 是 systemd 的标准接口,但设计上明确排除了 root 用户:“Refusing operation on root user” 是常见报错。它只对通过 logind 管理的普通会话有效(如 GNOME、SSH 登录的非 root 用户)。
- 可用
loginctl list-users验证:root 通常不显示在列表中 - 对普通用户如
bob,loginctl terminate-user bob会干净结束其所有 session(包括 GUI 和 terminal) - 不要试图用
--all或通配符绕过限制,无效且无日志提示
安全踢出“除当前外所有用户”的实操方案
核心思路:获取当前会话的 TTY(如 pts/0),再用 pkill -KILL -t 批量干掉其他 TTY。必须在本地终端(tty1)或已启用 PermitRootLogin console 的 SSH 配置下操作。
- 查当前 TTY:
tty→ 输出类似/dev/tty1,取后缀tty1;或echo $TTY(部分环境) - 列出所有活跃 TTY(排除自己):
w | awk 'NR>2 && $2 != "tty1" && $2 !~ /^:/ {print $2}' | sort -u - 逐个踢出:
for t in $(w | awk 'NR>2 && $2 != "tty1" && $2 !~ /^:/ {print $2}' | sort -u); do pkill -KILL -t "$t"; done - 更稳妥的写法(加 sleep 避免并发冲突):
for t in $(w | awk 'NR>2 && $2 != "tty1" {print $2}' | grep -v '^:' | sort -u); do pkill -KILL -t "$t"; sleep 0.3; done
为什么 fuser -k /dev/pts/* 不推荐
fuser -k /dev/pts/* 看似简单,但它会尝试 kill 所有 pts 设备上的进程,包括那些未在 w 中显示的孤儿进程或残留 fd,容易触发 "Permission denied" 报错,且无法区分目标用户——可能误杀监控脚本、systemd-journald 子进程等关键服务。
- 它不识别用户上下文,纯按设备路径暴力操作
- 在容器或 LXC 环境中,
/dev/pts/*可能映射到宿主机之外,行为不可控 - 真正需要“清空所有 pts”的场景极少,多数时候只是想清理 SSH 登录者
最易被忽略的一点:没有“全局下线开关”。Linux 登录管理本质是进程级的,而不同登录方式(SSH、getty、X11、Wayland)背后机制完全不同。所谓“踢用户”,实际是杀死其 shell 或 sshd 子进程;一旦用户启用了 screen、tmux 或后台 nohup 任务,仅 kill 终端进程并不能终止其业务逻辑——那得另查 ps -u username 再筛进程树。


















