自动化http请求脚本
#!/bin/bash # ============================================= # 一键算法镜像验证脚本 # 支持指定算法编号或默认验证 00-50 范围内存在的算法 # ============================================= # ========== 可配置参数区 ========== SCRIPT_DIR="/home/yaJiangBuild/team04/" # 启动脚本所在目录 IMAGE_SCRIPT_PREFIX="team04_algorithm" # 启动脚本前缀 ALGORITHM_START=0 # 算法编号起始 ALGORITHM_END=50 # 算法编号结束 TEST_IMAGE_PATH="/data/test" # 测试素材根路径 RESULT_ROOT_PATH="/data/picture-result" # 结果输出根路径(算法服务生成) AUTO_TEST_SCRIPT="/data/auto_test.sh" # 评测脚本路径 VIDEO_RESULT_ROOT_PATH="/data/video-result" HEALTH_CHECK_IP="127.0.0.1" # 健康检查和接口调用 IP HEALTH_CHECK_ENDPOINT="/health" # 健康检查端点 PICTURE_ANALYSIS_ENDPOINT="/picture/analysis" # 图片分析接口 VIDEO_ANALYSIS_ENDPOINT="/video/create" # 视频分析接口 RUN_TEST_LOG="/home/test" # 视频算法编号列表(其余视为图片算法) VIDEO_ALGORITHMS=(5 6 8 14 37) alg_handle_num=1 TEST_ID=$(date +%Y%m%d_%H%M%S) LOG_FILE="/data/logs/algorithm_verify_${TEST_ID}.log" # ============================================= source_id_global="" # 确保日志目录存在 LOG_DIR=$(dirname "$LOG_FILE") if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" || error_exit "无法创建日志目录: $LOG_DIR" fi # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" } image_exists() { local image="$1" docker inspect "$image" > /dev/null 2>&1 } # 停止并删除容器 stop_container() { local alg_id=$(printf "%02d" $((10#$1))) # 格式化为两位数 local container_name="team04_algorithm_${alg_id}" local timestamp=$source_id_global docker ps -a if image_exists "${container_name}"; then log "🧹 开始清理: $container_name" else log "🧹 清理完成: $container_name" exit 0 fi container_console_log_file="/data/tmp/team04/algorithm_${alg_id}/${container_name}_console_${timestamp}.log" log "😄 保存容器控制台日志: 容器名:$container_name, 容器日志文件路径:${container_console_log_file}" docker logs $container_name >> ${container_console_log_file} cp -rf ${container_console_log_file} "${RUN_TEST_LOG}/" log "🧹 正在清理容器: $container_name" if docker ps -a --format '{{.Names}}' | grep -qw "$container_name"; then if docker ps --format '{{.Names}}' | grep -qw "$container_name"; then docker stop "$container_name" > /dev/null 2>&1 && \ log "✅ 容器 $container_name 已停止" fi docker rm -f "$container_name" > /dev/null 2>&1 && \ log "✅ 容器 $container_name 已删除" else log "🔍 容器 $container_name 不存在,无需清理" fi alg_service_logs_file="/data/tmp/team04/algorithm_${alg_id}/logs_${timestamp}" if [[ -d "/data/tmp/team04/algorithm_${alg_id}/logs" ]]; then log "📁 算法分析服务日志文件: ${alg_service_logs_file}" mv "/data/tmp/team04/algorithm_${alg_id}/logs" ${alg_service_logs_file} log "✅ 容器控制台日志保存完成、算法服务日志备份完成" mkdir -p "${RUN_TEST_LOG}/${alg_id}" # 判断文件夹是否存在 if [ -d "${alg_service_logs_file}" ]; then log "📁 算法分析服务日志文件: ${alg_service_logs_file} 存在" cp -rf ${alg_service_logs_file}/* "${RUN_TEST_LOG}/${alg_id}/" else log "文件夹${alg_service_logs_file}不存在" fi else echo "文件夹不存在" fi } error_exit() { log "❌ 错误: $*" exit 1 } # 检查是否为图片算法 is_picture_algorithm() { local alg_num=$((10#$1)) # 使用10#强制转换为十进制 for vdo_alg in "${VIDEO_ALGORITHMS[@]}"; do if [[ "$vdo_alg" -eq "$alg_num" ]]; then return 1 fi done return 0 } # 获取素材数量(jpg 或 MP4) get_media_count() { local media_dir=$1 local count=0 if is_picture_algorithm "$ALG_ID"; then count=$(find "$media_dir" -maxdepth 1 -name "*.jpg" -o -name "*.JPG" -o -name "*.jpeg" -o -name "*.JPEG" | wc -l) echo "${count}" return 0 else # count=$(find "$media_dir" -maxdepth 1 -name "*.mp4" -o -name "*.MP4" | wc -l) # log "$ALG_ID video count $count" # 改为获取视频时长 # 视频:统计所有 .mp4 文件的总时长(秒) local total_duration=0 local duration local video_files=("$media_dir"/*.mp4 "$media_dir"/*.MP4) total_duration=0 for video_file in "${video_files[@]}"; do # 检查文件是否存在(避免通配符未匹配) [ -f "$video_file" ] || continue duration=$(ffprobe -v quiet -show_entries format=duration \ -of csv=p=0 "$video_file" 2>/dev/null || echo "0") if [[ "$duration" =~ ^[0-9]+\.?[0-9]*$ ]]; then total_duration=$(echo "$total_duration + $duration" | bc -l) fi done # 四舍五入保留 2 位小数(可选) total_duration=$(printf "%.2f" "$total_duration") echo "$total_duration" return 0 fi } # 等待容器启动并健康检查 wait_for_health() { local port=$1 local max_retries=60 local retry=0 local url="http://${HEALTH_CHECK_IP}:${port}${HEALTH_CHECK_ENDPOINT}" log "🔄 正在进行健康检查: $url" while [ $retry -lt $max_retries ]; do sleep 5 response=$(curl -s -w "%{http_code}" -X POST "$url" -H "Content-Type: application/json" --connect-timeout 5 -o /dev/null) if [ "$response" = "200" ]; then # 再检查返回 body 中 code 是否为 0 body=$(curl -s -X POST "$url" -H "Content-Type: application/json") code=$(echo "$body" | grep -o '"code":[0-9]*' | cut -d: -f2) if [ "$code" = "0" ]; then log "✅ 健康检查通过" return 0 else log "⚠️ 接口返回 code 非 0: $body" fi else log "⏳ 健康检查未通过 (HTTP $response),重试 $((retry+1))/$max_retries" fi retry=$((retry + 1)) done error_exit "❌ 健康检查超时或失败,终止算法 $ALG_ID 验证" } # 调用分析接口 trigger_analysis() { source_id_global="" local port=$1 local timestamp=$(date +%Y%m%d%H%M%S%3N) local source_id="${ALG_ID}-${timestamp}" log "source_id:$source_id" local task_id="${ALG_ID}-${timestamp}" local source_path="${TEST_IMAGE_PATH}/${ALG_ID}/" log "source_path:$source_path" if [ ! -d "$source_path" ]; then log "❌ 素材路径不存在: $source_path 跳过" return 0 fi local media_count=$(get_media_count "$source_path") log "ℹ️ 素材数量(图片是文件数据,视频是视频总时长): ${media_count}" if [[ "$media_count" == "0" || "$media_count" == "0.00" || "$media_count" == "0.0" ]]; then log "⚠️ 注意: 素材数量为 0: $source_path, media_count: ${media_count}" else log "ℹ️ 素材数量(图片是文件数据,视频是视频总时长): ${media_count}" fi local url local payload if is_picture_algorithm "$ALG_ID"; then url="http://${HEALTH_CHECK_IP}:${port}${PICTURE_ANALYSIS_ENDPOINT}" payload='{"sourceId":"'"$source_id"'","sourcePath":"'"$source_path"'"}' else url="http://${HEALTH_CHECK_IP}:${port}${VIDEO_ANALYSIS_ENDPOINT}" payload='{"taskId":"'"$task_id"'","sourcePath":"'"$source_path"'"}' fi log "🚀 调用分析接口: $url" log "📄 请求体: $payload" response=$(curl -s -w "%{http_code}" -X POST "$url" \ -H "Content-Type: application/json" \ -d "$payload" \ --connect-timeout 10 \ -o /tmp/curl_response_body.txt) http_code="${response: -3}" if [ "$http_code" != "200" ]; then error_exit "❌ 接口调用失败,HTTP 状态码: $http_code,响应: $(cat /tmp/curl_response_body.txt)" fi log "✅ 接口调用成功,响应: $(cat /tmp/curl_response_body.txt)" # 返回时间戳用于结果目录匹配 echo "$source_id" source_id_global="$source_id" } # 监控 end.log 生成 wait_for_end_log() { local identifier=$1 # 如 23-202508152100000 local max_wait=600 # 最大等待 10分 local check_interval=1 local result_dir="" local start_time=$(date +%s) # 查找 RESULT_ROOT_PATH 下所有以 "$ALG_ID-" 开头的目录,按修改时间排序取最新 local result_dir local result_dir_tmp if is_picture_algorithm "$ALG_ID"; then result_dir="$RESULT_ROOT_PATH/$identifier/end.log" result_dir_tmp="图片" else result_dir="$VIDEO_RESULT_ROOT_PATH/$identifier/end.log" result_dir_tmp="视频" fi log "🔍 监控结果目录中是否包含 end.log, 结果文件路径: ${result_dir}" echo -n "${result_dir_tmp}分析中:" while true; do echo -n "==" if [ -n "$result_dir" ] && [ -f "$result_dir" ]; then echo -e "\n" log "✅ 检测到 end.log: $result_dir" log "📁 end文件内容: $(cat ${result_dir})" break fi # local elapsed=$(( $(date +%s) - start_time )) # if [ $elapsed -ge $max_wait ]; then # error_exit "❌ 超时:$max_wait 秒内未生成 end.log" # fi sleep $check_interval done } convertDateTime(){ local timestamp=$1 # 截取各部分 year=${timestamp:0:4} # 2025 month=${timestamp:4:2} # 08 day=${timestamp:6:2} # 23 hour=${timestamp:8:2} # 16 minute=${timestamp:10:2} # 14 second=${timestamp:12:2} # 04 millisecond=${timestamp:14:3} # 059 # 拼接格式 formatted="${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond}" echo "$formatted" return 0 } # 计算推理时间并生成报告 duration: 单位毫秒 generate_report() { local start_time=$1 local a=$(convertDateTime $2) # 2025-08-23 16:14:04.059 转换成时间戳 end_time=$(date -d "$a" +%s%3N) log "转换后的时间戳: $end_time, a=$a" local duration=$((end_time - start_time)) local source_path="${TEST_IMAGE_PATH}/${ALG_ID}/" local media_count=$(get_media_count "$source_path") duration=$(echo "${duration} * 100" | bc) media_count=$(echo "${media_count} * 100" | bc) media_count=$(printf "%.0f" "$media_count") local avg_time_per_item=0 if [ "$media_count" -gt 0 ]; then avg_time_per_item=$(echo "scale=2; $duration / $media_count" | bc -l) fi log "end time:${end_time}" log "📊 推理时间报告:" log " 算法编号: $ALG_ID" log " 算法句柄数量: ${alg_handle_num}" log " 素材数量: $media_count 图片是文件,时间是总时长" log " 总耗时: ${duration}ms" log " 平均每项耗时: ${avg_time_per_item}ms" } # 执行评测脚本 run_evaluation() { log "🧪 正在执行评测脚本: $AUTO_TEST_SCRIPT $ALG_ID" if [ -x "$AUTO_TEST_SCRIPT" ]; then # 修改为指定算法编号 素材路径 sourceID log "⭐⭐⭐⭐⭐ 测评脚本执行中... 算法编号: $ALG_ID, 素材路径: ${TEST_IMAGE_PATH}, sourceID: ${source_id_global}" if "$AUTO_TEST_SCRIPT" "$ALG_ID" "${TEST_IMAGE_PATH}" "${source_id_global}" 2>&1 | tee -a "$LOG_FILE"; then log "✅ 评测执行成功" else log "⚠️ 评测脚本执行失败,退出码: $?" fi else log "⚠️ 评测脚本不存在或不可执行: $AUTO_TEST_SCRIPT" fi } # 验证单个算法 verify_algorithm() { ALG_ID=$(printf "%02d" $((10#$1))) # 格式化为两位数 # 设置 trap:无论脚本如何退出(正常或错误),都执行清理 trap 'stop_container $ALG_ID' EXIT log "🔍 开始验证算法: $ALG_ID" # 1. 查找启动脚本 SCRIPT_PATH="${SCRIPT_DIR}/${IMAGE_SCRIPT_PREFIX}_${ALG_ID}.sh" if [ ! -f "$SCRIPT_PATH" ]; then log "⏭️ 未找到启动脚本: $SCRIPT_PATH,跳过" return 0 fi #先判断路径是否存在 local source_path="${TEST_IMAGE_PATH}/${ALG_ID}/" log "source_path:$source_path" if [ ! -d "$source_path" ]; then log "❌ 素材路径不存在: $source_path 跳过" return 0 fi alg_handle_num=$(cat $SCRIPT_PATH | grep "AlgHdlSum=") # 2. 启动镜像 log "🐳 启动容器: $SCRIPT_PATH" if bash "$SCRIPT_PATH"; then log "✅ 容器启动命令执行成功" else error_exit "❌ 容器启动失败" fi # 3. 健康检查端口 PORT=$((10000 + 10#$ALG_ID)) # 10# 避免八进制解析 # 4. 等待健康检查通过 wait_for_health "$PORT" # 5. 调用分析接口,获取 source_id(含时间戳) # source_id=$(trigger_analysis "$PORT") trigger_analysis "$PORT" if [ -z "$source_id_global" ]; then log "❌ 未能获取 source_id" else log "sourceId trigger_analysis: ${source_id_global}" # 记录开始时间ms START_TIME=$(date +%s%3N) log "start time:$START_TIME" # 6. 监控 end.log # result_dir=$() wait_for_end_log "$source_id_global" local result_dir_end_log_tmp if is_picture_algorithm "$ALG_ID"; then result_dir_end_log_tmp="$RESULT_ROOT_PATH/${source_id_global}/end.log" else result_dir_end_log_tmp="$VIDEO_RESULT_ROOT_PATH/${source_id_global}/end.log" fi # 读取 end.log 第一行作为时间戳 end_timestamp=$(cat "$result_dir_end_log_tmp" | head -n1 | tr -d '\r\n') # 验证是否为纯数字时间戳(可选) if [[ "$end_timestamp" =~ ^[0-9]{17}$ ]]; then log "✅ 检测到 end.log 并读取时间戳: $end_timestamp" else log "⚠️ end.log 内容格式错误(非17位时间戳): $end_timestamp, 使用系统时间" end_timestamp=$(date "+%Y%m%d%H%M%S%3N") fi echo "$end_timestamp" # 7. 生成报告 generate_report "$START_TIME" "$end_timestamp" # 8. 执行评测 run_evaluation # 分析算法输出结果 verify_alg_result $1 fi # 9停止镜像 stop_container $1 log "✅ 算法 $ALG_ID 验证完成\n" } # 验证所有算法分析结果 # 验证所有算法分析结果 verify_alg_result() { local alg_id=$(printf "%02d" $((10#$1))) # 格式化为两位数 local dataPath="${TEST_IMAGE_PATH}/${alg_id}" # 素材路径 local result_dir="" local count="" local result_count="" if is_picture_algorithm "$1"; then result_dir="$RESULT_ROOT_PATH/${source_id_global}" result_dir_tmp="图片" count=$(find "${dataPath}" -maxdepth 1 -name "*.jpg" -o -name "*.JPG" -o -name "*.jpeg" -o -name "*.JPEG" | wc -l) result_count=$(find "${result_dir}" -maxdepth 1 -name "*.json" | wc -l) else result_dir="$VIDEO_RESULT_ROOT_PATH/${source_id_global}" result_dir_tmp="视频" count=$(find "${dataPath}" -maxdepth 1 -name "*.mp4" -o -name "*.MP4" | wc -l) return 0 fi log "📊 ${result_dir_tmp}算法分析结果目录: ${result_dir}, ${result_dir_tmp}分析结果数量:${result_count}" log "📊 ${result_dir_tmp}目录:${dataPath}, ${result_dir_tmp}数量:${count}" if [ "${result_count}" -eq 0 ]; then log "❌ ${result_dir_tmp}分析结果为0,可能是分析失败" return 0 fi # result_count != count if [ "${result_count}" -ne "${count}" ]; then log "❌ ${result_dir_tmp}分析结果数量不匹配: ${result_count} != ${count}" return 0 fi # 挨个校验 结果的json文件 local result_ok=0 local result_fail=0 echo -n "${result_dir_tmp}结果分析中..." for file in ${result_dir}/*; do ext="${file##*.}" filename=$(basename "$file") base="${filename%.*}" if [[ "$ext" != "json" ]]; then continue fi # 获取json内容 if [[ -s "$file" ]]; then file_content=$(cat $file) code=$(echo "${file_content}" | jq -r '.code') if [[ "$code" -eq 0 ]]; then result_ok=$((result_ok+1)) else log "❌ code 不为 0,错误码: $code, 结果文件:${file}" result_fail=$((result_fail+1)) fi else log "❌ 检测结果为空 可能检测失败" fi echo -n "." done echo -e "\n" log "✅ ${result_dir_tmp}分析结果校验完成: 成功 ${result_ok}, 失败 ${result_fail}" } # ============ 主程序 ============ main() { log "🎉📌📌📌📌📌📌📌 日志保存在: $RUN_TEST_LOG" local target_alg=$1 TEST_IMAGE_PATH=$2 if [ -z "$TEST_IMAGE_PATH" ]; then TEST_IMAGE_PATH="/data/test" echo "默认素材路径: $TEST_IMAGE_PATH" fi echo "素材路径: $TEST_IMAGE_PATH" folder_name=$(basename "$TEST_IMAGE_PATH") echo "文件夹: $folder_name" TEST_ID="${folder_name}_${TEST_ID}" echo "TEST_ID: $TEST_ID" RUN_TEST_LOG="${RUN_TEST_LOG}/${TEST_ID}" mkdir -p $RUN_TEST_LOG LOG_FILE="/data/logs/algorithm_verify_${TEST_ID}.log" echo "LOG_FILE: $LOG_FILE" # 输入IP HEALTH_CHECK_IP=$3 if [ -z "$HEALTH_CHECK_IP" ]; then HEALTH_CHECK_IP="127.0.0.1" echo "IP地址: $HEALTH_CHECK_IP" fi echo "IP地址: $HEALTH_CHECK_IP" if [ -z "$target_alg" ]; then log "📌 验证所有的需要 输入 all" elif [ "$target_alg" == "all" ]; then log "📌 默认验证算法编号 $ALGORITHM_START 到 $ALGORITHM_END 中存在的镜像" for i in $(seq $ALGORITHM_START $ALGORITHM_END); do if is_picture_algorithm "$i"; then echo "分析图片$i" else echo "分析视频$i" fi verify_algorithm "$i" done elif [ "$target_alg" == "images" ]; then log "📌 仅测试图片算法的镜像" image_alg_ids=(12 13 18 22 23 24 25 26 28 31 32 33 34 7 9) for image_alg_id in "${image_alg_ids[@]}"; do if is_picture_algorithm "$image_alg_id"; then echo "分析图片$image_alg_id" else echo "分析视频$image_alg_id" fi verify_algorithm "$image_alg_id" done elif [[ $target_alg == array* ]]; then echo "✅ 测试指定多个算法编号:$target_alg" # 去掉前缀 array: target_alg=${target_alg#array:} log "✅✅✅✅✅ 目标算法编号: $target_alg" # 逗号分割 IFS=',' read -r -a array <<< "$target_alg" for alg_id in "${array[@]}"; do echo "算法编号:${alg_id}" if is_picture_algorithm "$alg_id"; then echo "分析图片$alg_id" else echo "分析视频$alg_id" fi verify_algorithm "$alg_id" done elif [ "$target_alg" == "temp" ]; then log "📌 仅测试图片算法的镜像" image_alg_ids=(7 13 22 25) for image_alg_id in "${image_alg_ids[@]}"; do if is_picture_algorithm "$image_alg_id"; then echo "分析图片$image_alg_id" else echo "分析视频$image_alg_id" fi verify_algorithm "$image_alg_id" done elif [ "$target_alg" == "video" ]; then log "📌 仅测试视频算法的镜像" video_alg_ids=(14 37 5 6 8) for video_alg_id in "${video_alg_ids[@]}"; do if is_picture_algorithm "${video_alg_id}"; then echo "分析图片${video_alg_id}" else echo "分析视频${video_alg_id}" fi verify_algorithm "${video_alg_id}" done else if [[ "$target_alg" =~ ^[0-9]{1,2}$ ]] && [ "$target_alg" -ge $ALGORITHM_START ] && [ "$target_alg" -le $ALGORITHM_END ]; then log "📌 正在验证指定算法: $target_alg" verify_algorithm "$target_alg" else error_exit "❌ 无效的算法编号: $target_alg,应为 $ALGORITHM_START-$ALGORITHM_END 之间的整数" fi fi log "🎉 所有验证任务完成,日志保存在: $LOG_FILE" log "🎉🎉🎉📌📌📌📌📌📌 日志保存在: $RUN_TEST_LOG" cp $LOG_FILE ${RUN_TEST_LOG} } # ============ 执行 ============ main "$@"
自己开发了一个股票智能分析软件,功能很强大,需要的关注微信公众号:QStockView

浙公网安备 33010602011771号