|
@@ -0,0 +1,115 @@
|
|
|
|
+#!/bin/bash
|
|
|
|
+set -e
|
|
|
|
+set -x
|
|
|
|
+
|
|
|
|
+log() {
|
|
|
|
+ local message="$1"
|
|
|
|
+ echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a /var/log/spider_daemon.log
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function main() {
|
|
|
|
+ local workPath="/mnt"
|
|
|
|
+ local procName="zgzbtb_spider_m.py"
|
|
|
|
+
|
|
|
|
+ # 检查参数是否提供
|
|
|
|
+ if [ -z "$procName" ]; then
|
|
|
|
+ echo "Usage: $0 <process_name>"
|
|
|
|
+ exit 1
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ cd "$workPath" || { log "Failed to change directory to $workPath"; exit 1; }
|
|
|
|
+
|
|
|
|
+ local pids=$(pgrep -f "$procName")
|
|
|
|
+
|
|
|
|
+ # $? = 保存最后一个执行的命令的退出状态码,这里是指 launchProc 启动的进程
|
|
|
|
+ if launchProcWithLock "$workPath" "$procName" "$pids"; then
|
|
|
|
+ log "Process launched successfully, skipping further checks."
|
|
|
|
+ exit 0
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ checkProc "$pids"
|
|
|
|
+ clearZombieProc
|
|
|
|
+ launchProcWithLock "$workPath" "$procName" "$pids"
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function clearZombieProc() {
|
|
|
|
+ zombieProc="$(ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}')"
|
|
|
|
+ if [ -z "$zombieProc" ]; then
|
|
|
|
+ log "no detect zombie process(es)"
|
|
|
|
+ else
|
|
|
|
+ log "kill zombie process(es)...{$zombieProc}"
|
|
|
|
+ ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9
|
|
|
|
+ fi
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function launchProcWithLock() {
|
|
|
|
+ local workPath=$1
|
|
|
|
+ local procName=$2
|
|
|
|
+ local pids=$3
|
|
|
|
+ if [ -z "$pids" ]; then
|
|
|
|
+ local lockfile=""$workPath"/"$procName""
|
|
|
|
+ # 打开文件描述符7指向锁文件
|
|
|
|
+ exec 7<"$lockfile" || { log "Failed to open lockfile: $lockfile"; exit 1; }
|
|
|
|
+ if flock -xn 7; then
|
|
|
|
+ nohup python3 "$procName" >/dev/null 2>&1 &
|
|
|
|
+ log "launch '$procName' success, PID: $!" # $! = 最近一次在后台运行的进程的PID(进程标识符)
|
|
|
|
+ exec 7<&- # 关闭文件描述符7
|
|
|
|
+ return 0
|
|
|
|
+ else
|
|
|
|
+ log "Process(es) '$procName' is already running."
|
|
|
|
+ exec 7<&-
|
|
|
|
+ return 1
|
|
|
|
+ fi
|
|
|
|
+ else
|
|
|
|
+ log "Process(es) with PID(s) $pids are already running."
|
|
|
|
+ return 1
|
|
|
|
+ fi
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function checkProc() {
|
|
|
|
+ local pids=$1
|
|
|
|
+ for pid in $pids; do
|
|
|
|
+ # 获取进程的启动时间
|
|
|
|
+ startTime=$(ps -o lstart= -p $pid)
|
|
|
|
+
|
|
|
|
+ # 将startTime转换为日期格式
|
|
|
|
+ startDate=$(date -d "$startTime" +%s)
|
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
|
+ log "Error: Invalid date format for PID $pid: $startTime"
|
|
|
|
+ continue
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ # 获取当前时间(秒)
|
|
|
|
+ nowDate=$(date +%s)
|
|
|
|
+
|
|
|
|
+ # 计算运行时间(秒)
|
|
|
|
+ runtimeSec=$((nowDate - startDate))
|
|
|
|
+
|
|
|
|
+ # 转换为更易读的格式
|
|
|
|
+ days=$((runtimeSec / 86400))
|
|
|
|
+ runtimeSec=$((runtimeSec % 86400))
|
|
|
|
+ hours=$((runtimeSec / 3600))
|
|
|
|
+ runtimeSec=$((runtimeSec % 3600))
|
|
|
|
+ minutes=$((runtimeSec / 60))
|
|
|
|
+ seconds=$((runtimeSec % 60))
|
|
|
|
+
|
|
|
|
+ if [ ${seconds} -ge 5 ]; then
|
|
|
|
+ # 尝试发送终止信号,让进程自行处理退出操作
|
|
|
|
+ kill -9 "$pid"
|
|
|
|
+ log "kill process $pid"
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ log "Process ID: $pid"
|
|
|
|
+ log "Start Time: $startTime"
|
|
|
|
+ log "Runtime: ${days} days, ${hours} hours, ${minutes} minutes, and ${seconds} seconds"
|
|
|
|
+ log "----------------------------------"
|
|
|
|
+ done
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+main
|
|
|
|
+
|