ulimit -a 显示当前 shell 的全部资源限制,第二列为软限制、第三列为硬限制,单位依选项而异(如 -n 为个、-c 为512字节块、-s 为kb),unlimited 表示未设上限但受内核或pam约束。

直接看结果:用 ulimit -a 就能列出当前 shell 的全部资源限制,其中每行的第二列是软限制(soft limit),第三列是硬限制(hard limit)——但注意,它只反映当前会话的设置,不等于系统全局或某进程实际生效的值。
ulimit -a 输出怎么看单位和含义
执行 ulimit -a 后你会看到类似这样的输出:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 128192 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 128192 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
关键点:
- 括号里的单位(如
blocks、kbytes、files)必须结合选项理解:-n单位是“个”,不是字节;-c是 512 字节块;-s是 KB -
unlimited表示该限制未设上限,但不等于真的无上限——它可能被内核参数(如/proc/sys/fs/file-max)或 PAM 模块截断 - 软限制可由用户自行调高(只要不超过硬限制),硬限制只能由 root 修改
为什么 ulimit -a 显示 1024,但程序却报 “too many open files”?
因为 ulimit -a 只显示**当前 shell 启动时继承的限制**,而真正决定进程行为的是它启动那一刻的软限制。常见脱节场景:
- 服务以 systemd 启动时,
ulimit设置被忽略,需在 service 文件里加LimitNOFILE=65536 - 用户登录后手动执行
ulimit -n 65536,但后续用sudo或su -切换用户,新 shell 会重载 limits.conf,覆盖掉你刚设的值 - Java 进程通过
java -jar启动,若没在启动脚本里显式调用ulimit -n,它就沿用父 shell 的初始值(常为 1024) -
/etc/security/limits.conf配置了,但没启用pam_limits.so,或用户是通过 ssh 密钥免密登录(绕过某些 PAM session 模块)
如何确认某个正在运行的进程实际用了多少文件描述符
别只信 ulimit -a,要看真实进程状态:
- 先查 PID:
ps aux | grep nginx或pgrep -f "java.*myapp" - 再查它的实时限制:
cat /proc/<code>PID/limits | grep "Max open files" —— 这里显示的是该进程启动时锁定的软/硬限制,不可再改 - 再看它当前打开了多少文件:
ls /proc/<code>PID/fd | wc -l,这个数超过软限制就会触发错误 - 如果发现
/proc/<code>PID/limits 里Max open files是 1024,但你明明在 shell 里设过 65536,说明该进程根本没继承那个设置——大概率是它没从那个 shell 启动,或者启动时 shell 的 ulimit 已被重置
最易被忽略的一点:修改 /etc/security/limits.conf 后,普通用户必须完全退出并重新登录(不是新开 terminal 标签页),才能让新会话加载新限制;root 用户改完也建议用 su - $USER 测试,而不是只信当前 root shell 的 ulimit -a。











