You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本偶发‘Integer expression expected’错误排查求助

排查Bash脚本内存阈值判断的错误问题

你这个脚本的核心问题出在提取内存使用率的逻辑不够严谨,当系统中存在多个带"worker"关键字的进程时,你的命令会返回多行结果,导致memory_usage变量里包含多个数值,最终在整数比较时触发错误。

先来看你的原始脚本:

#!/bin/bash
memory_usage=`ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |cut -d "" -f2 | cut -d "-" -f1 | grep worker | cut -d M -f 1`
echo "Memory usage is ${memory_usage}"
int_memory_usage=${memory_usage%.*}
echo "Int Memory usage is ${int_memory_usage}"
if [ "${int_memory_usage}" -gt 16000 ]; then
    echo "Memory for worker ${memory_usage} above threshold"
    pkill -f "worker"
fi

错误原因分析

从报错信息Memory usage is 4261.01 0.34可以看出,memory_usage变量里有两个数值,这说明你的ps+grep worker命令匹配到了多个进程——比如一个真正的worker进程,还有可能包含脚本自身的grep worker进程,或者其他带worker关键字的进程。

当变量里有多个值时,int_memory_usage=${memory_usage%.*}只会去掉最后一个值的小数部分,导致int_memory_usage变成4261.01 0,后续的[ "${int_memory_usage}" -gt 16000 ]自然无法处理非单一整数的情况,抛出integer expression expected错误。

另外,你的cut -d "" -f2是无效的——cut的分隔符不能是空字符串,这部分其实是多余的,反而会干扰结果提取。

修复方案

我们需要优化进程筛选和内存提取逻辑,确保只获取目标worker进程的内存值,并且处理多进程场景:

方案1:只监控内存占用最高的worker进程

如果你的需求是只要有worker进程内存超过阈值就杀掉所有worker,那么可以只提取内存最高的那个worker进程的数值:

#!/bin/bash
# 提取内存最高的worker进程的内存值(只取第一行,排除awk/grep自身进程)
memory_usage=$(ps -eo size,pid,user,command --sort -size | awk '/worker/ && !/awk/ && !/grep/ { hr=$1/1024; printf("%.2f", hr); exit }')

# 处理没有worker进程的边界情况
if [ -z "$memory_usage" ]; then
    echo "No worker processes found."
    exit 0
fi

echo "Memory usage is ${memory_usage}"
# 用awk转整数比字符串截取更可靠
int_memory_usage=$(awk -v mem="$memory_usage" 'BEGIN{print int(mem)}')
echo "Int Memory usage is ${int_memory_usage}"

if [ "$int_memory_usage" -gt 16000 ]; then
    echo "Memory for worker ${memory_usage} above threshold"
    pkill -f "worker"
fi

方案2:逐个检查每个worker进程的内存

如果需要精准杀掉单个超阈值的进程(而非一刀切),可以遍历所有worker进程逐个判断:

#!/bin/bash
# 遍历所有worker进程,获取PID和内存值,逐个判断并处理
ps -eo size,pid,command --sort -size | awk '/worker/ && !/awk/ && !/grep/ {
    hr=$1/1024
    mem_int=int(hr)
    printf("Worker PID %d: %.2f Mb\n", $2, hr)
    if (mem_int > 16000) {
        printf("Killing worker PID %d (memory exceeds threshold)\n", $2)
        system("kill " $2)
    }
}'

关键优化点

  • 用awk直接过滤进程,排除awk和grep自身的进程,避免误匹配
  • 用awk的int()函数转换整数,比字符串截取更可靠,不会受多值干扰
  • 增加了无worker进程的边界处理,避免空值导致的错误
  • 方案2可以精准控制单个进程,减少不必要的进程终止

内容的提问来源于stack exchange,提问作者tusharmakkar08

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:20:52