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

Bash脚本循环修改JSON镜像名遇jq数组索引错误求助

问题:修改ECS任务定义镜像名称时触发jq错误

执行Bash脚本修改JSON格式的ECS任务定义镜像时,遇到如下错误:

jq: error (at :1): Cannot index array with string "0"

我的Bash循环代码:

NEW_IMAGE='xxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/virtual-layer-robot:xxxxxx'
for (( i=1 ; i<=10 ; i++ ));
do
    NEW_IMAGE=$NEW_IMAGE$i
    j=$((i-1))
    NEW_TASK_DEFINITION=$(echo $TASK_DEFINITION | jq -r --arg IMAGE "$NEW_IMAGE" --arg j "$j" '.taskDefinition | .containerDefinitions[$j].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del (.registeredBy)')
done

对应的TASK_DEFINITION JSON结构:

{"taskDefinition": {"taskDefinitionArn": "arn:aws:ecs:eu-west-1:xxxxxx:task-definition/virtual-xxxx-robot-task-xxxxxx:38","containerDefinitions": [{"name": "virtual-robot-1","image": "xxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/virtual-layer-robot:xxxxxx","cpu": 0,"portMappings": [{"containerPort": 89,"hostPort": 89,"protocol": "tcp"}],"essential": false,"environment": [{"name": "CROSS_ACCOUNT_ROLE","value": "arn:aws:iam::xxxxxxx:role/xxxxxx-xxx-xxxxxx-xxxx"}],"mountPoints": [],"volumesFrom": [],"logConfiguration": {"logDriver": "awslogs","options": {"awslogs-create-group": "true","awslogs-group": "/ecs/virtual-layer-robot-2010","awslogs-region": "eu-west-1","awslogs-stream-prefix": "ecs"}}},{"name": "virtual-robot-2","image": "xxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/virtual-layer-robot:xxxxxx","cpu": 0,"portMappings": [{"containerPort": 89,"hostPort": 89,"protocol": "tcp"}],"essential": false,"environment": [{"name": "CROSS_ACCOUNT_ROLE","value": "arn:aws:iam::xxxxxxx:role/xxxxxx-xxxx-xxxxxx-xxxxx"}],"mountPoints": [],"volumesFrom": [],"logConfiguration": {"logDriver": "awslogs","options": {"awslogs-create-group": "true","awslogs-group": "/ecs/virtual-layer-robot-2010","awslogs-region": "eu-west-1","awslogs-stream-prefix": "ecs"}}}]},"tags": []}

错误原因与修正方案

1. 核心错误:jq索引类型不匹配

--arg传递的参数是字符串类型,你的$j是字符串"0"、"1"等,但jq数组需要用数字索引,所以会触发"Cannot index array with string"错误。

解决方法二选一:

方法一:用tonumber转字符串为数字

修改jq命令中的索引部分:

.containerDefinitions[$j|tonumber].image = $IMAGE

方法二:用--argjson直接传递数字参数

把--arg j "$j"替换为--argjson j "$j",这样$j直接以数字类型传入,无需转换:

NEW_TASK_DEFINITION=$(echo "$TASK_DEFINITION" | jq -r --arg IMAGE "$NEW_IMAGE" --argjson j "$j" '.taskDefinition | .containerDefinitions[$j].image = $IMAGE | del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)')

2. 镜像名称拼接逻辑错误

你当前的NEW_IMAGE=$NEW_IMAGE$i会导致镜像名累加:

  • 第1次循环:NEW_IMAGE变成原始值1
  • 第2次循环:变成原始值12
  • 以此类推,完全不符合每个容器对应原始值+i的预期

应该保留原始镜像前缀,每次循环重新拼接:

# 把前缀定义在循环外
IMAGE_PREFIX='xxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/virtual-layer-robot:xxxxxx'
for (( i=1 ; i<=10 ; i++ ));
do
    NEW_IMAGE="${IMAGE_PREFIX}${i}"  # 每次生成独立的镜像名
    j=$((i-1))
    # 后续jq命令不变(已修复索引问题)
done

3. 循环次数超出容器数量

你的JSON里只有2个容器,但循环跑10次,当i>=3时,j=2会超出数组索引范围(数组索引从0开始,最大为1),触发新的jq错误。

建议根据容器数量动态调整循环次数:

# 先获取容器总数
CONTAINER_COUNT=$(echo "$TASK_DEFINITION" | jq '.taskDefinition.containerDefinitions | length')
for (( i=1 ; i<=CONTAINER_COUNT ; i++ ));
do
    # 循环逻辑
done

优化后的完整脚本

IMAGE_PREFIX='xxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/virtual-layer-robot:xxxxxx'
# 获取原始任务定义的容器数量
CONTAINER_COUNT=$(echo "$TASK_DEFINITION" | jq '.taskDefinition.containerDefinitions | length')

# 初始化新任务定义为原始值,避免每次循环从原始数据重新修改
NEW_TASK_DEFINITION="$TASK_DEFINITION"

for (( i=1 ; i<=CONTAINER_COUNT ; i++ ));
do
    NEW_IMAGE="${IMAGE_PREFIX}${i}"
    j=$((i-1))
    NEW_TASK_DEFINITION=$(echo "$NEW_TASK_DEFINITION" | jq -r --arg IMAGE "$NEW_IMAGE" --argjson j "$j" '.taskDefinition |= (.containerDefinitions[$j].image = $IMAGE | del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy))')
done

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:08:08