如何通过sh文件实现运行超30分钟的PHP cron任务自动终止
自动终止超时Yii2 Cron任务的实现方案
你可以直接修改原有sh脚本,增加运行时长检测和超时杀死逻辑,以下是两种可选实现:
方案1:完整自定义逻辑(支持日志记录、多进程兼容)
修改后的sh脚本内容如下:
#!/bin/bash # 任务标识 CRON_TASK="cron/my-cron-action" # Yii入口文件完整路径 YII_PATH="/home/public_html/full-path-to-project/yii" # 最大允许运行时长,单位:分钟 MAX_RUN_MINUTES=30 # 查找所有运行中的目标任务进程ID RUNNING_PIDS=$(ps -ef | grep -v grep | grep "$CRON_TASK" | awk '{print $2}') if [ -n "$RUNNING_PIDS" ]; then # 遍历所有进程检测运行时长 for PID in $RUNNING_PIDS; do # 计算进程已运行的分钟数,兼容小时、天级的运行时长格式 RUN_MINUTES=$(ps -p "$PID" -o etime= | awk -F '[:-]' '{ if(NF==2) {print $1/60} else if(NF==3) {print $1} else if(NF==4) {print $1*24 + $2} }' | awk '{print int($1)}') # 超时则强制杀死进程,可选写入日志方便排查 if [ "$RUN_MINUTES" -ge "$MAX_RUN_MINUTES" ]; then kill -9 "$PID" echo "$(date '+%Y-%m-%d %H:%M:%S') 已杀死超时进程 $PID,累计运行 $RUN_MINUTES 分钟" >> /var/log/cron_task.log fi done # 处理完超时进程后,再次检查是否仍有存活的同任务进程,有则退出避免并发 if ps -ef | grep -v grep | grep "$CRON_TASK" > /dev/null; then exit 0 fi fi # 启动新的任务进程 php "$YII_PATH" "$CRON_TASK" exit 0
注意事项:
- 脚本自动兼容了运行时长低于1小时、高于1小时、高于1天的三种进程时间格式,不会出现计算错误
- 可根据实际业务需要调整
MAX_RUN_MINUTES的阈值 - 日志路径可自行修改,无需日志可以删除echo对应的行
方案2:轻量快速实现(用系统自带timeout命令)
如果不需要额外的日志和定制逻辑,直接用Linux内置的timeout命令即可限制任务最大运行时长,修改原有脚本为:
if ps -ef | grep -v grep | grep cron/my-cron-action; then exit 0 else # 30m代表最大运行30分钟,-k 5表示首次终止失败后5秒强制杀死进程 timeout -k 5 30m php /home/public_html/full-path-to-project/yii cron/my-cron-action exit 0 fi
参数说明:
- 时间支持单位:s(秒)、m(分钟)、h(小时)、d(天)
-k 5为可选参数,不配置的话超时后会先发送默认终止信号,进程如果未响应会一直保留
内容的提问来源于stack exchange,提问作者Mukesh Godara
相关产品推荐
相关产品推荐

