直接运行 ulimit -a 可查看当前 shell 所有资源的软限制值;要分别查看某项的软/硬限制,需用 ulimit -sn / ulimit -hn 等带 -s 或 -h 标志的命令。

怎么用 ulimit 查看当前 shell 的软硬限制
直接运行 ulimit -a 就能看到所有资源的软限制值(即当前生效值)。它不区分软硬,只显示你此刻能用的上限——这个值就是软限制。
要单独看某项的软/硬限制,必须加 -S 或 -H 标志:
-
ulimit -Sn显示当前 shell 的“打开文件数”软限制(比如 1024) -
ulimit -Hn显示对应硬限制(比如 65536) -
ulimit -Su和ulimit -Hu分别查进程数限制
注意:ulimit 查的是**当前 shell 环境**的限制,不是系统全局值,也不是某个后台服务的实际限制。如果你在 systemd 启动的 nginx 里看到 “Too many open files”,ulimit -n 的结果很可能和 nginx 进程无关。
/proc/self/limits 能看到更真实的进程级限制
每个进程在启动时继承其父进程(通常是 shell)的 ulimit 设置,但一旦启动完成,它的限制就固化在 /proc/[pid]/limits 里了。运行 cat /proc/self/limits 可以看到当前 shell 进程的完整软硬限制表,字段清晰:Limit、Soft Limit、Hard Limit、Units。
这对排查问题特别有用:
- 如果
ulimit -n显示 65536,但cat /proc/self/limits | grep "Max open files"显示 Soft Limit 是 1024,说明你当前 shell 并没真正应用新限制(可能改了配置但没重登录) - 对某个 Java 进程,用
cat /proc/$(pgrep -f 'java.*app')/limits | grep files能确认它到底被卡在哪个值上 - 输出里的
Max processes对应-u,Max file size对应-f,命名和 ulimit 参数不完全一致,别按字面硬套
ulimit 常用参数和单位陷阱
ulimit 多数参数的单位不是字节或个数,而是抽象块或 KB,容易误判:
-
-c(core file size):单位是 512 字节块。设ulimit -c 0是禁 core,ulimit -c 100表示最多 51200 字节 -
-d(data seg size)、-s(stack size):单位是 KB -
-f(file size):默认单位也是 512 字节块;ulimit -f 1024= 最大 512KB 文件 -
-n(open files)、-u(processes):单位是**个数**,这是少数直观的参数
执行 ulimit -a 时,右边的单位会一并列出(如 “open files (-n) 1024”),但很多人扫一眼就跳过。临时调高文件数时,写 ulimit -n 65536 没问题;但调堆栈大小,ulimit -s 8192 是 8MB,不是 8KB。
为什么改了 limits.conf 还不生效
最常踩的坑是以为编辑完 /etc/security/limits.conf 就立刻全局生效。实际上它只在用户**新登录会话**中加载,且依赖 PAM 正确调用:
- SSH 登录、图形界面登录、
su - username都算“新会话”;但su username(不带 -)不会重载 limits - 检查
/etc/pam.d/sshd或/etc/pam.d/common-session是否有session required pam_limits.so;缺这行,limits.conf 形同虚设 - systemd 服务(如
nginx.service)默认不读 limits.conf,必须在 service 文件里显式写LimitNOFILE=65536,再systemctl daemon-reload && systemctl restart xxx - 容器内进程(如 docker run)通常继承宿主 init 进程的限制,而非容器用户的 limits.conf
真正生效的路径是:limits.conf → PAM session → login shell → 子进程。中间任一环断开,ulimit 看到的就还是旧值。











