ulimit -a 显示的是当前 shell 的软限制,不是全局配置,仅反映当前会话的资源限制;真正生效的进程限制需查 /proc/$pid/limits,systemd 服务则必须通过 LimitNOFILE 在 unit 文件中单独配置。

ulimit -a 显示的是当前 shell 的软限制,不是全局配置
直接运行 ulimit -a 看到的只是你当前终端会话的软限制值,它由登录时 PAM 加载的 /etc/security/limits.conf 或 /etc/security/limits.d/*.conf 决定,但只对新启动的进程生效。已运行的服务(比如 systemd 启动的 nginx)完全不受影响。
常见错误现象:你在终端里执行 ulimit -n 得到 65536,但 ps aux | grep nginx 找到的 nginx 进程打开文件数卡在 1024 —— 这说明 nginx 没继承你的 shell 限制,而是用了自己的 unit 配置或默认值。
-
ulimit -Sn和ulimit -Hn分别查当前 shell 的软/硬限制,单位是“个数”,别和-s(栈大小,单位 KB)混淆 - 普通用户只能调低硬限制,或把软限制提到不超过硬限制的值;提硬限制必须 root
- 临时设置如
ulimit -n 65536只对当前 shell 及其后续 fork 的子进程有效,退出就丢
/proc/$pid/limits 是唯一真实反映进程实际限制的路径
要确认某个具体进程(比如 PID 1234)到底被设了什么限制,cat /proc/1234/limits 是最准的方式。它不依赖配置文件是否加载、不看 shell 环境,而是内核为该进程维护的实时快照。
输出里每行三列:Limit、Soft Limit、Hard Limit、Units。例如 Max open files 行告诉你这个进程此刻真能开多少文件,不是“应该能”,而是“已经被 kernel 锁死的数”。
- 普通用户只能读自己进程的
/proc/$pid/limits,读别人会报Permission denied;root 可全读 - 如果看到
unlimited,不代表没约束——可能被 cgroup 或 systemd 的LimitNOFILE=覆盖,得接着查systemctl show myapp.service | grep LimitNOFILE -
/proc/self/limits是查看当前 shell 进程自身限制的快捷方式,等价于cat /proc/$$/limits
/etc/security/limits.conf 里的配置不一定生效
改了 /etc/security/limits.conf 后,ulimit -n 还是旧值?大概率是因为你没重新登录,或者服务压根没走 PAM 登录流程。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
该文件只对通过 login、su、ssh 等 PAM 认证方式启动的交互式会话生效。systemd 服务、cron job、docker 容器、screen/tmux 会话都不走这套逻辑。
- 检查是否启用 pam_limits.so:运行
grep limits /etc/pam.d/common-session(Debian/Ubuntu)或/etc/pam.d/login(RHEL/CentOS),确认有required pam_limits.so - 配置语法必须严格:
username soft nofile 65536中空格不能用 tab,soft/hard不能写错,nofile不能拼成no-file - 若使用通配符
*,注意它不匹配 root;root 需单独配,或用root行覆盖
systemd 服务的资源限制优先级最高,且独立于 limits.conf
用 systemctl start nginx 启动的服务,它的限制由 systemd unit 文件控制,/etc/security/limits.conf 对它完全无效。
查法很简单:systemctl show nginx.service | grep -i limit。重点关注 LimitNOFILE=、LimitNPROC=、LimitCORE= 这些字段。它们默认继承自 /etc/systemd/system.conf 中的 DefaultLimit* 设置。
- 修改方法:在
/etc/systemd/system/nginx.service.d/override.conf里加[Service]段,写LimitNOFILE=65536,然后systemctl daemon-reload && systemctl restart nginx - 不要试图用
prlimit -p 1234 --nofile=65536:65536临时改 systemd 服务——它会被下一次 reload 或重启立刻覆盖 -
systemctl status nginx输出里的 “Memory limit”、“CPU limit” 等,也来自 cgroup v2 配置,和 ulimit 无关
真正容易被忽略的点是:同一个资源(比如打开文件数),可能在四个地方被分别设限——内核参数 fs.file-max、systemd 默认值、unit 文件显式配置、PAM limits.conf。最终生效的是其中最严的那个,而且它们互不感知。 查问题时,必须按进程来源逐层定位,不能只看 ulimit -a。

















