首先,一个非常简单的代码:
#!/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[@]}"以及输出
string
1
1
0因此,用readarray -t将空字符串读入bash数组时,数组长度为1,而且只有真正的空数组长度为0。
我的问题-为什么会发生?
作为我的案例--下面是我的脚本中的一个片段--执行一个API调用,获取JSON,并应用jq过滤器:
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调用中得到一个空数组:
[
{
"Header": {
"Region": "dc1",
"Tenant": "tenant1",
"Stage": "test"
},
"Body": {
"monitors": []
}
}
]下面是具有填充内容的JSON,从jq调用返回一个非空数组:
[
{
"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 语句检查字符串是否为空,如果非空,则将字符串分配给数组,但这会引入其他元素。使用这种方法,我可以完全跳过使用数组--我希望只使用数组来完成这项任务。
谢谢
发布于 2020-09-27 20:30:46
为什么会发生这种事?
因为它读的是一行。来自bash手册此处文档
n<<<词..。结果作为一个字符串()提供给它的标准输入上的命令(如果指定了n,则为文件描述符n),并附加了一个换行符。
因为有一个换行符,readarray读取一个空行。你可以这样做:
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'并检查退出状态。https://stackoverflow.com/questions/64092857
复制相似问题