最准确的方式是直接查看 /proc/$pid/limits,它反映进程当前真实生效的软硬限制,不依赖 shell 会话、PAM 或 systemd 配置;例如 cat /proc/1234/limits | grep "Max open files" 输出中第三列为软限制、第四列为硬限制,单位明确,且仅 root 可查看所有进程。

/proc/$pid/limits 是最准的,它反映目标进程当前真实生效的软硬限制,不依赖 shell 会话是否加载了配置、也不受 PAM 或 systemd 的延迟影响。
怎么看某个服务进程的实际限制?
别信 ulimit -n 输出——那只是你当前终端的设置,跟 nginx、redis 这类 daemon 完全无关。
- 先用
ps aux | grep nginx找到主进程 PID(通常是 master 进程,不是 worker) - 再执行
cat /proc/1234/limits | grep "open files"(把 1234 换成实际 PID) - 输出类似
Max open files 1024 65536 files,左边是 soft,中间是 hard,单位写在最后 - 如果查不到,说明你没权限:普通用户只能看自己启动的进程;root 才能看所有进程
ulimit -a 和 /proc/self/limits 有什么区别?
ulimit -a 显示的是当前 shell 启动时继承的软限制快照,而 /proc/self/limits 是内核为这个 shell 进程维护的实时状态表,字段更全、单位更明确。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
ulimit -a不显示硬限制值,只列软限;cat /proc/self/limits两列都给,且带 Units 列(比如bytes、files) -
ulimit -s输出单位是 KB,但/proc/self/limits里Max stack size单位是字节,数值大 1024 倍 - 某些资源如
Max pending signals、Max file locks在ulimit -a里根本不出现,只能从/proc/self/limits看到
为什么改了 /etc/security/limits.conf 却没生效?
因为该文件只对通过 PAM 登录的交互式会话生效,systemd 服务、cron job、docker 容器、SSH 非登录 shell 都不走这套流程。
- 确认服务是否由 systemd 启动:运行
systemctl status myapp.service - 查 systemd 的限制覆盖项:
systemctl show myapp.service | grep LimitNOFILE,它优先级高于 limits.conf - 如果是 Docker 容器,得看
docker run --ulimit nofile=65536:65536是否传入,容器内ulimit -n和宿主机无关 - 即使改了 limits.conf,也得重新登录或重启对应服务才能加载新限制,已运行进程不会自动更新
怎么验证修改真的起作用?
别只改完就跑,一定要用目标进程的 /proc/$pid/limits 反向验证。
- 改完
/etc/security/limits.conf后,用新用户登录再启动程序,再查/proc/$pid/limits - 用
prlimit -p 1234 --nofile=65536:65536临时调高运行中进程的限制后,立刻cat /proc/1234/limits确认是否写入成功 - 注意:如果输出仍是旧值,可能是被 cgroup 或 systemd 的
LimitNOFILE拦截了,得去对应 unit 文件里加LimitNOFILE=65536 -
/proc/$pid/limits里某项显示unlimited不代表没限制,可能被内核参数fs.file-max或 cgroup 的pids.max实际卡住
cat /proc/$pid/limits 看它此刻到底被设成了多少。

















