从root用户切换到某个普通用户突然报错“su: failed to execute /bin/bash: 资源暂时不可用”

背景:

当你从 root 用户使用 su 切换到某个普通用户时,出现错误:

复制代码
su: failed to execute /bin/bash: 资源暂时不可用

这个错误的英文原文通常是:

复制代码
su: failed to execute /bin/bash: Resource temporarily unavailable

这表示系统在尝试为新用户启动 shell(这里是 /bin/bash)时,由于某种资源限制而失败。尽管你是 root,但目标用户的会话仍然受到其用户级别的资源限制约束。

常见原因及排查方法:


✅ 1. 用户进程数(max user processes)达到上限

这是最常见的原因。系统对每个用户允许运行的最大进程数有限制(由 ulimit -u 控制)。

排查方法:

复制代码
# 查看当前 root 的进程数限制
ulimit -u

# 查看目标普通用户当前的进程数(切换前可用)
ps -u username --no-heading | wc -l

如果该用户已经有大量进程在运行(例如后台脚本、ssh 会话、screen/tmux 等),再 su 就可能无法创建新进程。

解决方法:

  • 终止该用户无用的进程:

    复制代码
    pkill -u username
    # 或者更谨慎地 kill
    pkill -u username command_name
  • 临时提高限制(需修改 limits.conf):

    复制代码
    # 编辑 /etc/security/limits.conf
    username    soft    nproc    4096
    username    hard    nproc    8192

    注意:修改后需重新登录才生效。


✅ 2. 系统级进程/线程数接近上限

查看系统整体的进程数限制和当前使用情况:

复制代码
# 查看最大线程数(也限制进程数)
cat /proc/sys/kernel/threads-max
cat /proc/sys/kernel/pid_max

# 查看当前系统已使用的进程数
ps aux | wc -l

如果系统接近这些上限,也会导致无法创建新进程。


✅ 3. 内存不足或OOM(Out of Memory)

虽然错误提示不是"内存不足",但在极端内存耗尽的情况下,内核可能拒绝 fork 新进程。

检查:

复制代码
free -h
dmesg | grep -i "oom\|kill"
journalctl | grep -i "oom\|kill"

如果看到 Out of memory: Kill process,说明系统曾因内存不足杀掉进程,可能导致资源紧张。


✅ 4. PAM 或 limits 配置问题

PAM 模块(如 pam_limits.so)在 su 时会加载用户的资源限制。如果 /etc/security/limits.conf 设置过严,或 PAM 配置缺失,可能导致问题。

确认 /etc/pam.d/su 是否包含:

复制代码
session    required   pam_limits.so

如果没有这行,ulimit 设置可能不生效或异常。


✅ 5. 目标用户的 shell 被占用或异常

极少数情况下,如果用户的 shell(如 /bin/bash)被大量进程占用,或 shell 初始化脚本(.bashrc, .profile)中有死循环/无限递归,也可能导致"资源不可用"。

测试方法:

复制代码
su - username -s /bin/sh

尝试换一个更轻量的 shell,看是否成功。


✅ 6. 容器或虚拟化环境资源限制

如果你在 Docker、LXC、Kubernetes 或某些虚拟化环境中,宿主机可能对容器设置了严格的 cgroup 限制(如 pids.limit)。

检查:

复制代码
# 查看当前 cgroup 的进程数限制
cat /sys/fs/cgroup/pids/user.slice/user-$(id -u).slice/pids.max
cat /sys/fs/cgroup/pids/user.slice/user-$(id -u).slice/pids.current

如果 pids.current 接近 pids.max,说明已达上限。


✅ 快速诊断命令总结:

复制代码
# 1. 查看目标用户当前进程数
ps -u username | wc -l

# 2. 查看系统进程总数
ps aux | wc -l

# 3. 检查 limits
ulimit -a

# 4. 查看是否有 OOM
dmesg | grep -i oom
journalctl | grep "killed process"

# 5. 检查 cgroup 限制(如有)
cat /sys/fs/cgroup/pids/pids.max

✅ 解决方案建议:

  1. 重启或清理目标用户的进程(最直接)。
  2. 调整 /etc/security/limits.conf ,增加 nproc 限制。
  3. 确保 pam_limits.so 已启用
  4. 检查系统资源(内存、进程总数)是否充足
  5. 在容器环境中检查 cgroup 限制

请根据你的环境运行上述诊断命令,定位具体是哪种资源受限。如果提供 ps -u usernameulimit -a 的输出,可以进一步帮你分析。

相关推荐
小猪写代码4 小时前
bash zsh sh与shell 有什么关系
开发语言·bash
fish-man6 小时前
测试流程图展示问题
linux·服务器·流程图
-dcr6 小时前
16.Linux RAID 存储技术
linux·运维·服务器
yuanManGan6 小时前
走进Linux的世界:gdb的使用
linux·运维·服务器
ZYMFZ6 小时前
Linux系统Nginx服务(二)
linux·运维·nginx
yolo_guo7 小时前
glog使用: 07-错误信号处理(Failure Signal Handler)
linux·c++·glog
维尔切7 小时前
MySQL 主从复制
linux·运维·数据库·mysql·adb
挺6的还7 小时前
38.应用层协议HTTP(一)
linux
小猪写代码7 小时前
Linux-ARM-裸机开发-开发环境搭建
linux·arm开发