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

如何将tee的输出重定向到变量/数组而非文件(curl+jq场景)

如何将tee的输出重定向到变量/数组而非文件(curl+jq场景)

兄弟我太懂你这痛点了!之前我也踩过bash子shell变量隔离的坑,咱们一步步把这个问题解决掉~

首先得给你说清楚为什么你之前的read my_array[index]没用:bash里的>(...)这种进程替换会创建一个子shell,子shell里的变量(包括你的数组)和父shell是完全隔离的——子shell里就算把值存进去了,父shell根本看不到,所以读完之后你的数组还是空的,这是bash的固有特性,不是你写的有问题!

接下来给你两个靠谱的解决方案,你可以根据自己的习惯选:

方案一:先存整个响应,再分别处理(最推荐,逻辑清晰)

其实完全不用tee分流,咱们先把curl的整个JSON响应存到一个变量里,再用jq分别提取dataId和next_token就行,这样完全绕开子shell的问题:

# 初始化变量和数组
next_token="your_initial_token"  # 这里填API要求的初始token,比如空字符串或者第一个请求的默认值
my_array=()
index=0

while [[ "$next_token" != "null" ]]; do
    # 先把curl的完整响应抓下来存到变量
    response=$(curl -u "$user:$password" "https://mylink.dot")
    
    # 从响应里提取所有dataId,逐个追加到数组
    # 用while read处理jq输出的每一行(因为dataSummaries是数组,可能多个id)
    while read -r data_id; do
        my_array[index]="$data_id"
        index=$((index + 1))
    done < <(echo "$response" | jq -r '.dataSummaries[] | .dataId')
    
    # 提取下一页的next_token
    next_token=$(echo "$response" | jq -r '.nextToken')
done

# 测试一下数组内容
echo "所有提取到的dataId:"
printf "%s\n" "${my_array[@]}"

这个方案的好处就是逻辑直白,所有变量和数组都在父shell里操作,绝对不会出现“存了但看不到”的情况。要是你的API可能返回空的dataSummaries数组,记得把jq的表达式改成.dataSummaries[]? | .dataId,加个问号就能忽略空数组的报错了。

方案二:用命名管道实现tee式分流(适合非要保留tee逻辑的场景)

如果你特别想用tee来分流响应,那可以用命名管道代替进程替换的子shell,让父shell直接从管道里读数据:

# 初始化变量
next_token="your_initial_token"
my_array=()
index=0

while [[ "$next_token" != "null" ]]; do
    # 创建两个临时命名管道
    mkfifo data_pipe next_token_pipe
    
    # 用tee把curl响应分流到两个管道,同时把curl后台运行避免阻塞
    curl -u "$user:$password" "https://mylink.dot" | tee >(jq -r '.dataSummaries[] | .dataId' > data_pipe) >(jq -r '.nextToken' > next_token_pipe) > /dev/null &
    
    # 从data_pipe里读dataId到数组
    while read -r data_id; do
        my_array[index]="$data_id"
        index=$((index + 1))
    done < data_pipe
    
    # 从next_token_pipe里读下一页的token
    read -r next_token < next_token_pipe
    
    # 用完管道记得删掉,避免残留
    rm data_pipe next_token_pipe
done

# 验证结果
printf "提取到的dataId列表:\n%s\n" "${my_array[@]}"
echo "最后获取的next_token:$next_token"

这个方案用命名管道作为数据中转,父shell直接从管道读数据,变量和数组都能正常保存。不过要注意创建管道后记得删除,不然下次运行可能出问题。

总的来说,方案一的可读性和维护性更好,除非你有特殊需求,不然优先选方案一就对了~

备注:内容来源于stack exchange,提问作者dzafer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:54:33