什么是 ulimit?
ulimit 是一个 Linux/Unix shell 内建命令,用于控制 shell 及其启动的进程所能使用的资源,你可以把它理解为系统为每个用户进程设置的一个“资源使用上限”,通过 ulimit,系统管理员和普通用户可以限制程序在 CPU 时间、内存、文件描述符、最大进程数等方面消耗的资源,从而防止某个失控的程序耗尽系统资源,影响其他用户和整个系统的稳定性。

为什么需要 ulimit?
想象一个场景:一个用户不小心运行了一个有内存泄漏的程序,如果没有 ulimit 限制,这个程序可能会不断消耗系统内存,最终导致系统变慢甚至崩溃,影响到所有其他用户。
ulimit 的主要作用包括:
- 系统稳定性:防止恶意或有缺陷的程序耗尽系统资源。
- 资源管理:在多用户环境中,公平地分配资源。
- 调试与开发:开发时可以限制程序资源,模拟资源受限的环境,或防止调试程序意外占用过多资源。
- 服务部署:在启动关键服务(如 Web 服务器、数据库)前,设置合适的资源上限,确保服务稳定运行。
ulimit 的基本用法
ulimit 命令的基本语法如下:
# 查看当前限制 ulimit [选项] # 设置新的限制 ulimit [选项] [新限制值]
ulimit 的限制分为两种:

- 软限制:当前生效的限制值,用户可以调低软限制,或者调高软限制但不能超过硬限制。
- 硬限制:用户能设定的最大限制值,通常只有 root 用户才能提高硬限制。
不带任何选项执行 ulimit 默认显示的是文件描述符的软限制。
常用选项和资源类型
ulimit 支持多种资源类型,通过不同的选项来指定。
| 选项 | 资源类型 | 描述 |
|---|---|---|
-a |
(all) | 显示所有当前资源限制,这是最常用的选项之一。 |
-c |
(core) | 核心文件的大小 (单位: KB),设置为 0 可以阻止生成核心文件。 |
-d |
(data) | 进程数据段的最大大小 (单位: KB)。 |
-f |
(file) | 创建文件的最大大小 (单位: KB),这是默认选项。 |
-l |
(lock) | 在内存中锁定地址空间的最大大小 (单位: KB)。 |
-n |
(file) | 可以打开的最大文件描述符数量。在高并发服务器上至关重要。 |
-p |
(pipe) | 管道缓冲区的大小 (单位: KB)。 |
-s |
(stack) | 栈的最大大小 (单位: KB)。 |
-t |
(cpu) | 最大 CPU 时间 (单位: 秒),进程达到此限制后将被终止。 |
-u |
(nproc) | 单个用户可以拥有的最大进程数。 |
-v |
(as) | 地址空间的最大大小 (单位: KB)。 |
-H |
(hard) | 操作硬限制。 |
-S |
(soft) | 操作软限制,这是默认行为。 |
--help |
显示帮助信息。 |
实用示例
示例 1:查看所有当前限制
使用 -a 选项可以一目了然地看到所有资源的限制值。
$ ulimit -a core file size (blocks, -c) 0 # 核心文件大小为0,不生成 data seg size (kbytes, -d) unlimited # 数据段大小无限制 scheduling priority (-e) 0 # 调度优先级 file size (blocks, -f) unlimited # 单个文件大小无限制 pending signals (-i) 15608 # 挂起的信号数量 max locked memory (kbytes, -l) 65536 # 最大锁定内存64MB max memory size (kbytes, -m) unlimited # 最大内存使用无限制 open files (-n) 1024 # 最大打开文件数1024 (非常重要) pipe size (512 bytes, -p) 8 # 管道大小 POSIX message queues (bytes, -q) 819200 # POSIX消息队列大小 real-time priority (-r) 0 # 实时优先级 stack size (kbytes, -s) 8192 # 栈大小8MB cpu time (seconds, -t) unlimited # CPU时间无限制 max user processes (-u) 15608 # 单用户最大进程数 virtual memory (kbytes, -v) unlimited # 虚拟内存无限制 file locks (-x) unlimited # 文件锁数量
示例 2:查看和修改文件描述符限制
在高并发应用(如 Nginx, Node.js)中,-n (文件描述符限制) 是一个非常关键的参数。
# 1. 查看当前文件描述符软限制 $ ulimit -n 1024 # 2. 查看当前文件描述符硬限制 $ ulimit -Hn 1048576 # 3. 临时修改软限制为 65535 (仅对当前 shell 及其子进程有效) $ ulimit -n 65535 $ ulimit -n 65535 # 4. 尝试修改硬限制 (普通用户会失败,需要 root 权限) $ ulimit -Hn 65536 -bash: ulimit: max user processes: cannot modify limit: Operation not permitted
注意:这种修改方式是临时的,只在当前终端会话及其启动的子进程中有效,关闭终端后,设置就会失效。
示例 3:限制 CPU 时间
假设你想让一个脚本最多运行 10 秒,超时就自动终止。
# 设置 CPU 时间上限为 10 秒 $ ulimit -t 10 # 运行一个会消耗 CPU 的命令 (一个简单的死循环) $ while :; do true; done # 10 秒后,该进程会自动被系统终止,并返回错误码 124 # [Ctrl+C] 可以手动终止
示例 4:限制核心文件大小
默认情况下,程序异常崩溃时可能会生成一个巨大的核心文件,占用大量磁盘空间,可以将其设为 0 来禁用。
# 查看当前核心文件大小限制 $ ulimit -c 0 # 设置核心文件大小为 0 (禁用) $ ulimit -c 0 # 或者设置为 1024 KB (1MB) $ ulimit -c 1024
如何永久设置 ulimit?
临时设置在重启或关闭 shell 后就会失效,要让设置永久生效,需要将其写入配置文件,根据你使用的 shell,配置文件不同。
- Bash Shell:
~/.bashrc,~/.bash_profile,/etc/profile,/etc/security/limits.conf - Zsh Shell:
~/.zshrc,/etc/security/limits.conf
最推荐的方式是使用 /etc/security/limits.conf 文件,因为它专门用于系统级别的资源限制,并且对 PAM (Pluggable Authentication Modules) 友好。
编辑 /etc/security/limits.conf 文件:
sudo vim /etc/security/limits.conf
文件中的每一行格式为:
<username|@group> <type> <item> <value>
<username|@group>: 用户名或 开头的用户组名。<type>:soft,hard, 或 (代表同时设置 soft 和 hard)。<item>: 资源类型,如nofile,nproc,core等。<value>: 限制值。
示例:
-
为
www-data用户(Nginx 运行用户)设置文件描述符限制:# 在文件末尾添加 www-data soft nofile 65535 www-data hard nofile 65535
或者用简写:
www-data - nofile 65535
-
为所有用户设置默认限制:
# 在文件末尾添加 * soft nofile 1024 * hard nofile 4096
重要提示:
- 修改
/etc/security/limits.conf后,用户需要重新登录才能使新限制生效。 - 对于
systemd管理的服务,还需要在服务的 unit 文件中设置LimitNOFILE=,因为limits.conf对某些服务可能不直接生效。
ulimit 与 systemd 的关系
在现代使用 systemd 的 Linux 发行版中(如 Ubuntu 16.04+, CentOS 7+),服务资源限制更推荐在 systemd 的 unit 文件中设置。systemd 的限制会覆盖 limits.conf 中对特定服务的设置。
为 nginx.service 设置文件描述符限制:
-
编辑 unit 文件(通常在
/etc/systemd/system/目录下,或直接修改/lib/systemd/system/nginx.service):[Service] # ... 其他配置 ... LimitNOFILE=65535
-
重新加载 systemd 并重启服务:
sudo systemctl daemon-reload sudo systemctl restart nginx
| 特性 | 描述 |
|---|---|
| 用途 | 控制单个进程或用户能使用的系统资源。 |
| 范围 | 限制范围是当前 shell 及其所有子进程。 |
| 临时性 | 直接在命令行执行是临时的。 |
| 永久性 | 需要写入 ~/.bashrc, /etc/profile 或 /etc/security/limits.conf。 |
| 关键资源 | -n (文件描述符), -u (进程数), -c (核心文件), -s (栈大小)。 |
| 现代替代 | 对于系统服务,优先使用 systemd unit 文件中的 Limit* 指令。 |
掌握 ulimit 是进行 Linux 性能调优和系统管理的重要技能,尤其是在处理高并发应用时。
