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

如何在Bash中将动态值存储为数组变量?

解决方案:正确将Azure Key Vault秘密数据存储为Bash数组

问题根源

当前脚本中getapp和getserviceprincipal被赋值为命令输出的字符串而非数组,Bash不会自动将多行输出拆分为数组元素;同时两次调用az keyvault secret list可能因数据更新导致两组结果不匹配,循环条件也存在语法错误。

修改后的完整脚本

#!/bin/bash

ExpirationDate=$(date -d '+60 days' +'%Y-%m-%d')
VaultName="abc"

# 一次API调用获取所有需要的字段,用jq按"SecretName|Type"格式输出每行
readarray -t secrets < <(az keyvault secret list --vault-name "$VaultName" \
  --query "[?attributes.expires<='$ExpirationDate'].{SecretName:name, Type:contentType}" \
  | jq -r '.[] | "\(.SecretName)|\(.Type)"')

# 初始化目标数组
declare -a getapp=()
declare -a getserviceprincipal=()

# 拆分每行数据到对应数组
for secret in "${secrets[@]}"; do
    IFS='|' read -r app sp <<< "$secret"
    getapp+=("$app")
    getserviceprincipal+=("$sp")
done

# 遍历数组执行操作
for ((i=0; i<${#getapp[@]}; i++)); do
    echo "${getapp[$i]}"
    ./resetpassword.sh -a "${getapp[$i]}" -s "${getserviceprincipal[$i]}" -y
    echo "${getserviceprincipal[$i]}"
done

关键优化点

  1. 单次API调用
    避免两次调用az命令,防止两次请求之间秘密状态变化导致数据不匹配,同时减少API开销。通过jq将每个秘密的名称和类型用|拼接成单行,确保数据一一对应。

  2. 正确读取数组
    使用readarray -t secrets将命令输出的每行内容直接转为数组元素,-t参数自动去除每行末尾的换行符。

  3. 安全拆分数据
    通过IFS='|'指定分隔符,将每行内容拆分为秘密名称和类型,分别存入目标数组,避免空格等特殊字符导致的拆分错误。

  4. 修正循环逻辑
    用i<${#getapp[@]}作为循环条件,确保遍历所有数组元素,替换原脚本中i-le$len-1的语法错误。

备选方案(直接转数组)

如果坚持分两次调用API,可通过以下方式将输出直接转为数组:

# 将getapp转为数组,IFS设为换行避免空格拆分元素
IFS=$'\n' read -r -d '' -a getapp < <(az keyvault secret list --vault-name "$VaultName" \
  --query "[?attributes.expires<='$ExpirationDate'].name" | jq -r '.[]')

# 同理处理getserviceprincipal
IFS=$'\n' read -r -d '' -a getserviceprincipal < <(az keyvault secret list --vault-name "$VaultName" \
  --query "[?attributes.expires<='$ExpirationDate'].contentType" | jq -r '.[]')

注:此方案仍存在两次API调用导致数据不一致的风险,优先推荐单次调用的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:54:53