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

Bash脚本处理Git提交JSON文件时重复调用API问题求助

问题:Git提交的JSON文件被重复执行API调用

提交file1.json至file5.json共5个文件时,每个文件被重复执行5次,期望每个文件仅执行一次。尝试用数组记录已处理文件但未生效。

问题原因

  1. 数组匹配逻辑缺陷:原脚本用[[ ! " ${processed_files[@]} " =~ " ${file} " ]]判断文件是否已处理,当文件名包含特殊字符(如空格、*)或匹配边界模糊时,会导致判断失效,重复处理同一文件。
  2. 文件名遍历方式错误:直接用for file in $files遍历git diff输出,若文件名包含空格会被分割成多个元素,引发异常处理。
  3. CURL命令语法错误:原脚本中-F "$endpoint/deploy"将API URL错误当作表单字段,导致请求无效,可能触发重复执行逻辑。

解决方案

  1. 使用关联数组记录已处理文件,判断逻辑更可靠,不受文件名特殊字符影响。
  2. 用while read循环读取git diff输出,正确处理带空格的文件名。
  3. 修正CURL命令的语法,将API URL放在命令末尾,而非作为-F参数。
  4. 优化状态提取逻辑,避免依赖字符串切割的脆弱写法(可选,用jq工具更可靠)。

修正后的完整脚本

#!/bin/bash

# 用关联数组记录已处理文件,判断更可靠
declare -A processed_files

# Login配置
endpoint="xxx"
username="xxx"
password="xxx"
auth_token="xxx" # 替换为实际的授权令牌

# 获取提交中的文件列表,用while read正确处理带空格的文件名
git diff --name-only HEAD HEAD~1 | while read -r file; do
    # 仅处理JSON文件
    if [[ "$file" == *.json ]]; then
        # 判断文件是否已处理
        if [[ -z "${processed_files[$file]}" ]]; then
            # 标记为已处理
            processed_files["$file"]=1
            echo "开始执行任务:$file"
            
            # 部署操作:修正curl语法,URL放在末尾
            curl -k -s -H "Authorization: $auth_token" -X POST -F "definitionsFile=@../$file" "$endpoint/deploy"
            
            # 运行任务并获取runId
            submit=$(curl -k -s -H "Authorization: $auth_token" -X POST -F "jobDefinitionsFile=@../$file" "$endpoint/run")
            # 推荐用jq提取runId(若环境安装了jq):runid=$(echo "$submit" | jq -r '.runId')
            runid=$(echo "${submit##*runId\" : \"}" | cut -d '"' -f 1)
            
            # 等待任务结束
            echo "等待任务结束:$runId"
            while true; do
                sleep 10
                tmp=$(curl -k -s -H "Authorization: $auth_token" "$endpoint/run/status/$runid")
                
                # 检查任务是否失败
                if echo "$tmp" | grep -q 'Not OK'; then
                    echo "任务失败:$file"
                    curl -k -s -H "Authorization: $auth_token" -X POST "$endpoint/session/logout"
                    exit 2
                fi
                
                # 提取任务状态
                # 推荐用jq:status=$(echo "$tmp" | jq -r '.status')
                tmp2=$(echo "${tmp##*\"type\" : \"Folder\",\n}")
                status=$(echo "${tmp2##*\"status\" : \"}" | cut -d '"' -f 1)
                
                # 判断任务是否结束
                if [[ "$status" == Ended* ]]; then
                    echo "任务完成:$file"
                    break
                fi
            done
        else
            echo "任务已执行,跳过:$file"
        fi
    fi
done

# 登出
curl -k -s -H "Authorization: $auth_token" -X POST "$endpoint/session/logout"

# 最终状态判断
if [[ "$status" == *Not* ]]; then
    echo '任务执行失败!'
    exit 1
else
    echo '所有任务执行成功!'
    exit 0
fi

额外优化建议

  • 若环境允许,安装jq工具(sudo apt install jq或brew install jq),用jq提取JSON字段,替代脆弱的字符串切割,例如:
    runid=$(echo "$submit" | jq -r '.runId')
    status=$(echo "$tmp" | jq -r '.status')
    
  • 增加错误处理,比如检查curl命令是否执行成功,避免因网络问题导致后续逻辑出错。
  • 将敏感信息(如授权令牌)放在环境变量中,而非硬编码在脚本里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:15:36