Bash数组嵌套循环遍历AWS多Profile多区域输出CSV异常排查
问题根因
脚本存在核心逻辑错误,导致最终输出不符合预期:
- 文件写入方式错误:使用
>符号执行覆盖写入,每次调用AWS CLI查询时,都会先清空对应配置的CSV文件原有内容,再写入本次查询结果。三层循环全部跑完后,每个CSV文件只会保留最后一次循环对应的区域(即us-west-1)的查询结果。如果preprod、dev两个配置在us-west-1区域没有EC2实例,查询返回空内容,文件就会被覆盖为空,表现为无有效数据;prod配置在us-west-1有少量实例,就只保留了这部分内容。 - 边界逻辑缺失:直接执行
rm test/*.csv没有做容错处理,如果test目录不存在、或者目录下没有csv文件,命令会直接抛出错误;同时输出的CSV没有表头,后续查看无法对应字段含义。 - 可读性问题:原脚本外层遍历区域、内层遍历配置,和需求描述的遍历顺序相反,虽然不会直接导致结果错误,但后续调整逻辑时容易出错。
修复后完整脚本
#!/bin/bash # 初始化工作目录,强制清理旧文件避免报错 mkdir -p test rm -f test/*.csv declare -a profiles=("preprod" "dev" "prod") declare -a regions=("us-east-1" "us-east-2" "us-west-1") # 定义CSV表头,和查询字段一一对应 csv_header="InstanceId,InstanceType,State,LaunchTime,AvailabilityZone,Tenancy,PrivateIpAddress,NameTag,ServernameTag,StackTag,CostCenterTag,BusinessUnitTag,RITag,RIExpireTag" # 按需求顺序外层遍历配置,内层遍历区域 for profile in "${profiles[@]}"; do # 每个配置的CSV文件先写入表头 echo "$csv_header" > "test/${profile}.csv" for region in "${regions[@]}"; do # 查询结果用>>追加写入,不会覆盖之前区域的内容 aws ec2 describe-instances \ --output text \ --query 'Reservations[*].Instances[*].[InstanceId, InstanceType, State.Name, LaunchTime, Placement.AvailabilityZone, Placement.Tenancy, PrivateIpAddress,[Tags[?Key==`Name`].Value] [1][0], [Tags[?Key==`servername`].Value] [0][0], [Tags[?Key==`stack`].Value] [0][0], [Tags[?Key==`CostCenter`].Value] [0][0], [Tags[?Key==`business-unit`].Value] [0][0], [Tags[?Key==`RI`].Value] [0][0], [Tags[?Key==`RI Expire`].Value] [0][0] ]' \ --profile "$profile" \ --region "$region" >> "test/${profile}.csv" done done
修复说明
- 调整重定向逻辑:每个配置的CSV仅在初始化写表头时使用
>覆盖,后续所有区域的查询结果统一用>>追加写入,保证所有区域的数据都能完整保留 - 增加目录容错:用
mkdir -p自动创建不存在的test目录,rm -f忽略不存在的文件,避免命令报错中断脚本执行 - 调整循环顺序为「先配置、后区域」,和业务逻辑保持一致,降低后续维护成本
- 增加CSV表头,输出文件可直接用表格工具打开查看,不需要手动对应字段
内容的提问来源于stack exchange,提问作者tmac
相关产品推荐
相关产品推荐

