本文目录导读:

在Shell脚本中设置 ulimit 资源限制主要分为临时设置(仅对当前Shell及子进程生效)和永久设置(系统级或用户级),以下是详细说明:
基本语法
ulimit [选项] [限制值]
常用选项
| 选项 | 含义 | 单位 | 常用值 |
|---|---|---|---|
-n |
打开文件数 | 整数 | 65535 |
-u |
最大用户进程数 | 整数 | unlimited 或 65535 |
-c |
核心文件大小 | KB | unlimited |
-s |
堆栈大小 | KB | 8192 |
-d |
数据段大小 | KB | unlimited |
-m |
最大内存 | KB | unlimited |
-t |
CPU时间 | 秒 | unlimited |
-v |
虚拟内存 | KB | unlimited |
-f |
文件大小 | KB | unlimited |
在脚本中设置
示例脚本
#!/bin/bash # 在脚本开头设置资源限制 ulimit -n 65535 # 文件描述符 ulimit -u unlimited # 用户进程数 ulimit -c unlimited # 核心文件 ulimit -s 8192 # 堆栈大小(MongoDB等需要) ulimit -d unlimited # 数据段 # 检查是否设置成功 echo "当前限制:" ulimit -a # 执行需要高资源限制的程序 ./my_heavy_app
注意事项
⚠️ 重要:
- 只能降低限制:普通用户不能提高已有上限(需要root)
- 需要root权限:设置超过当前系统默认值
- 会话级别:仅在当前shell会话有效
分场景设置
场景1:为特定命令临时设置
#!/bin/bash ulimit -n 65535 -u unlimited && ./my_program
场景2:检查当前值并调整
#!/bin/bash
current_nofile=$(ulimit -n)
echo "当前文件描述符限制: $current_nofile"
if [ "$current_nofile" -lt 65535 ]; then
ulimit -n 65535 2>/dev/null || {
echo "警告: 无法设置文件描述符为65535"
echo "当前最大允许值: $(ulimit -n)"
}
fi
场景3:使用sudo提升权限
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "需要root权限设置ulimit"
exit 1
fi
ulimit -n 65535
ulimit -u 65535
./my_service
永久设置(系统级)
方法1:修改 /etc/security/limits.conf
# 文件: /etc/security/limits.conf # 格式: <domain> <type> <item> <value> * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535
方法2:PAM模块配置
# 文件: /etc/pam.d/common-session (Ubuntu) # 或 /etc/pam.d/login (CentOS) session required pam_limits.so
方法3:systemd服务限制
[Service] LimitNOFILE=65535 LimitNPROC=65535 LimitCORE=infinity
实际脚本案例
案例:启动一个需要高资源限制的Java服务
#!/bin/bash
SERVICE_NAME="my-java-app"
JAVA_HOME="/usr/lib/jvm/java-11"
APP_JAR="/opt/myapp/app.jar"
# 设置资源限制
set_limits() {
local list="
-n 65535 # 文件描述符
-u 65535 # 用户进程数
-c unlimited # 核心文件
-s 8192 # 栈大小
"
while read -r opt val desc; do
if ! ulimit "$opt" "$val" 2>/dev/null; then
echo "警告: 无法设置 $desc 为 $val"
echo "当前值: $(ulimit "$opt")"
fi
done <<< "$list"
echo "最终资源限制:"
ulimit -a | grep -E "open files|process|core|stack"
}
# 主逻辑
main() {
# 检查root
if [[ $EUID -ne 0 ]]; then
echo "请使用root或sudo运行此脚本"
exit 1
fi
# 设置限制
set_limits
# 启动应用
exec $JAVA_HOME/bin/java -jar $APP_JAR
}
main "$@"
检查当前限制的命令
# 查看所有限制 ulimit -a # 查看特定限制 ulimit -n # 文件描述符 ulimit -u # 进程数 # 查看系统级限制 cat /proc/sys/fs/file-max # 系统总文件描述符限制 cat /proc/sys/kernel/pid_max # 系统总PID限制
常见问题解决
问题1:ulimit: cannot modify limit: Operation not permitted
- 原因:非root用户尝试提高硬限制
- 解决:使用sudo或修改limits.conf
问题2:设置后不生效
- 原因:Shell的PAM配置未加载
- 解决:重新登录或重启服务
问题3:Docker容器内设置无效
- 解决:在docker run时添加
--ulimit参数docker run --ulimit nofile=65535:65535 ...
- 脚本内:使用
ulimit命令临时设置 - 系统级:修改
/etc/security/limits.conf - 服务级:使用systemd的Limit*指令
- 容器级:使用Docker的--ulimit参数
选择哪种方式取决于你的具体场景和权限级别。