首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当jq输出空字符串时bash readarray -t数组分配的问题

当jq输出空字符串时bash readarray -t数组分配的问题
EN

Stack Overflow用户
提问于 2020-09-27 20:09:04
回答 1查看 1.3K关注 0票数 8

首先,一个非常简单的代码:

代码语言:javascript
运行
复制
#!/bin/bash

a_string="string"
readarray -t a <<<"$a_string"
echo "${a[@]}"
echo "${#a[@]}"

# read empty string into array
emptystring=""
readarray -t b <<<"$emptystring"
echo "${b[@]}"
echo "${#b[@]}"

# and now - empty array
c=()
echo "${c[@]}"
echo "${#c[@]}"

以及输出

代码语言:javascript
运行
复制
string
1

1

0

因此,用readarray -t将空字符串读入bash数组时,数组长度为1,而且只有真正的空数组长度为0。

我的问题-为什么会发生?

作为我的案例--下面是我的脚本中的一个片段--执行一个API调用,获取JSON,并应用jq过滤器:

代码语言:javascript
运行
复制
URL_list_json=$(curl -s --request GET "$curl_request" --header "Authorization: Bearer ${token}")
readarray -t URL_names <<<"$(echo "$URL_list_json" | jq -r '.[].Body.monitors[].name')"

下面是JSON的一个示例,它从jq调用中得到一个空数组:

代码语言:javascript
运行
复制
[
    {
        "Header": {
            "Region": "dc1",
            "Tenant": "tenant1",
            "Stage": "test"
        },
        "Body": {
            "monitors": []
        }
    }
]

下面是具有填充内容的JSON,从jq调用返回一个非空数组:

代码语言:javascript
运行
复制
[
    {
        "Header": {
            "Region": "dc2",
            "Tenant": "tenant2",
            "Stage": "qa"
        },
        "Body": {
            "monitors": [
                {
                    "enabled": true,
                    "entityId": "TEST-674BA97E74FC74AA",
                    "name": "production.example.com"
                },
                {
                    "enabled": false,
                    "entityId": "TEST-3E2D23438A973D1E",
                    "name": "test.example.com"
                }
            ]
        }
    }
]

我需要检查URL_names数组是否为空。如果不为空,则遍历内容。如果为空-意味着jq没有返回任何结果-白色日志和继续前进。

如果我使用if ((${#URL_names[@]}))作为检查数组是否为空的手段,它将返回1,即使数组只有来自jq调用的空字符串,因此这个逻辑失败。

处理上述情况的替代方法是什么?

我可以将jq过滤器的输出分配给字符串,然后使用 if 语句检查字符串是否为空,如果非空,则将字符串分配给数组,但这会引入其他元素。使用这种方法,我可以完全跳过使用数组--我希望只使用数组来完成这项任务。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-27 20:30:46

为什么会发生这种事?

因为它读的是一行。来自bash手册此处文档

n<<<词..。结果作为一个字符串()提供给它的标准输入上的命令(如果指定了n,则为文件描述符n),并附加了一个换行符

因为有一个换行符,readarray读取一个空行。你可以这样做:

代码语言:javascript
运行
复制
readarray -t b < <(printf "%s" "$emptystring")

备注:

  • 不喜欢echo "$var"。在posix中执行printf "%s" "$var",在bash中执行<<<"$var" (您不关心额外的换行符)。
  • <<<"$(...)"看起来总是很奇怪--无论如何,<<<必须分配一个子subshell。做< <(...)
  • 你想做的事:readarray -t URL_names < <(<<<"$URL_list_json" jq -r '.[].Body.monitors[].name')
  • 如果要检查数组是否为空,请在jq中进行检查。我看到前男友了。 jq --exit-status '.[].Body.monitors[].name'并检查退出状态。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64092857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档