脚本中Ulimit资源限制如何设置

wen 实用脚本 12

本文目录导读:

脚本中Ulimit资源限制如何设置

  1. 基本语法
  2. 常用选项
  3. 在脚本中设置
  4. 分场景设置
  5. 永久设置(系统级)
  6. 实际脚本案例
  7. 检查当前限制的命令
  8. 常见问题解决

在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

注意事项

⚠️ 重要

  1. 只能降低限制:普通用户不能提高已有上限(需要root)
  2. 需要root权限:设置超过当前系统默认值
  3. 会话级别:仅在当前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参数

选择哪种方式取决于你的具体场景和权限级别。

抱歉,评论功能暂时关闭!