首页/系统/Linux 运维命令速查/场景:限制单个脚本的资源
进程与作业69 条

场景:限制单个脚本的资源

跑一个可能吃资源的脚本(转码/解析大文件):用子 shell + ulimit 兜底,超限被杀而不是拖垮整机。

Linux 运维命令速查系统更新于 2026-10-13

这个场景解决什么

跑一个可能吃资源的脚本(转码、解析超大文件、批处理)时最怕它把整机拖垮。用子 shell 加 ulimit 组成一次性的护栏,把地址空间、进程数、CPU 时间限住,再叠加 timeout 控制总时长,超限直接被杀而不是拖垮系统。长期方案应交给 systemd 单元或 cgroup 做精确计量。

基本信息

场景给临时任务设一次性资源上限
组合写法( ulimit 项; 命令 ) 子 shell 沙箱,再叠 timeout
常用项-v 地址空间、-u 进程数、-t CPU 时间、-n 打开文件数
退出码124 超时、137 被强杀、152 对应 CPU 时间超限

典型使用场景

  • 解析超大日志或导数据前做兜底,避免内存被吃光
  • 转码、压缩类 CPU 任务限住 CPU 时间,防止长期占用
  • 第三方脚本来源不明,先隔离在资源受限的子 shell 里跑
  • 批量任务并发前,先验证单个任务的资源画像
  • 定时任务里加护栏,防止异常数据触发失控
  • 复现线上问题时主动限资源,观察降级表现

常用护栏

常用护栏
( ulimit -v 2000000; ulimit -u 512; timeout 600 ./heavy.sh )   # 内存与进程数护栏
( ulimit -t 300; ./cpu-hog.sh )      # CPU 时间超过 300 秒被 SIGXCPU
( ulimit -n 1024; ./open-files.sh )  # 限制可打开文件数
echo "exit=$?"                       # 124=超时 137=被强杀 152=CPU 时间超限
ulimit -a                            # 先看当前 shell 的全部限制
( ulimit -v 500000; exec java --version )   # 验证限制是否会让程序起不来
systemd-run --scope -p MemoryMax=2G -p CPUQuota=50% ./heavy.sh   # 长期方案

常用限制项

选项含义超限表现
-v虚拟内存地址空间分配失败或直接退出
-u用户可创建进程数报资源暂时不可用
-tCPU 时间上限(秒)收到 SIGXCPU 结束
-n可打开文件数报打开文件过多
-c核心转储大小超限时不生成转储文件
ulimit -v 管的是地址空间而非实际驻留内存:Java、Go 等运行时会预留大块地址空间,限制给得太紧会直接起不来,这类应用改用 cgroup 的总内存限制更合适。
子 shell 里的限制只作用于这一条命令,父 shell 与后续命令不受影响——这正是护栏的意义。把 ulimit 写在子 shell 外面会连自己的登录会话一起限制。
长期且精确的资源限制应交给 systemd 单元(MemoryMax、CPUQuota、TasksMax)或 cgroup,它们基于 cgroup 计量,比 ulimit 更准确也更便于审计。

易错点

  • 用 ulimit -v 限制 Java 或 Go 任务:地址空间预留被计入,程序直接起不来
  • 把 ulimit 写在父 shell 里:影响之后的所有命令,连登录会话一起受限
  • 只看退出码不看含义:124 是超时、137 是被强杀,混为一谈会误判原因
  • 把 ulimit 当长期方案:仅对当前进程有效,服务重启后限制就消失了

数据来源与参考

  • man 1 bash(ulimit 内建)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌