如何修改Bash脚本实现杀死运行时长超过5小时的指定进程?
脚本修改方案
核心问题说明
你原来的脚本问题在于ps -o etime输出的格式不固定:
- 进程运行不足1小时:格式为
MM:SS,分割后数组长度为2 - 进程运行1小时以上、不足1天:格式为
HH:MM:SS,分割后数组长度为3 - 进程运行超过1天:格式为
DD-HH:MM:SS,分割后数组长度为4
原来直接取${time[1]}作为分钟数的逻辑完全无法适配长于1小时的进程,会取到错误的数值。
修改后完整脚本
#!/bin/bash # 配置项:进程名、超时阈值(单位:分钟,5小时即300分钟) PROC_NAME=my_proc_name MAX_RUN_MINS=300 # 获取目标进程PID,过滤掉grep自身进程 procs=(`ps aux | grep $PROC_NAME | grep -v grep | awk '{print $2}'`) for pid in "${procs[@]}"; do # 跳过空值(避免无匹配进程时循环报错) [ -z "$pid" ] && continue # 替换时间分隔符,按天、时、分、秒拆分到数组 time_arr=(`ps -o etime= -p "$pid" | sed -e 's/[-:]/ /g'`) len=${#time_arr[@]} total_mins=0 # 根据数组长度判断时间格式,计算总运行分钟数 if [ $len -eq 2 ]; then # 不足1小时:[分, 秒] total_mins=${time_arr[0]} elif [ $len -eq 3 ]; then # 1小时以上不足1天:[时, 分, 秒] total_mins=$(( ${time_arr[0]} * 60 + ${time_arr[1]} )) elif [ $len -eq 4 ]; then # 超过1天:[天, 时, 分, 秒] total_mins=$(( ${time_arr[0]} * 24 * 60 + ${time_arr[1]} * 60 + ${time_arr[2]} )) fi # 超过阈值则杀进程 if [ "$total_mins" -gt "$MAX_RUN_MINS" ]; then kill -9 "$pid" fi done
关键修改点说明
- 新增
MAX_RUN_MINS配置项,阈值直接填分钟数即可,5小时直接填300,后续调整也更方便 - 修正了PID获取逻辑,过滤掉
grep $PROC_NAME自身的进程,避免误杀 - 新增
ps -o etime=的参数,去掉输出的表头,避免解析到无关内容 - 兼容了所有可能的etime输出格式,统一换算为总运行分钟数再做判断,不会出现时长解析错误
- 增加了空PID判断,避免没有找到目标进程时脚本报错
内容的提问来源于stack exchange,提问作者Cataster
相关产品推荐
相关产品推荐

