用于读取进度状态的 Bash 循环在空变量上结束?

Bash loop for reading progress status ends on empty variable?

提问人:dataprolet 提问时间:8/22/2023 更新时间:8/22/2023 访问量:45

问:

我正在尝试读取下载进度的 RESTful API 状态的输出并将其打印出来。下载完成后,状态将从“正在运行”更改为“定期终止”,并且不再显示“进度”指示器。因此,循环以空变量 $progress 结束。

因此,以下脚本正确显示了下载进度,但下载完成后,脚本会突然结束,并且不显示“下载完成”。

假设下载正在会话 1 上运行。

while true; do
    status=$(curl -s -u admin:admin -H "Accept:application/json" -X GET \
    -i http://1.2.3.4/sessionInformation/1/status | grep "Status" | sed 's/    "Status"://g' | sed 's/"//g')

        while [[ $status != "terminated regularly"  ]]; do
            progress=$(curl -s -u admin:admin -H "Accept:application/json" -X GET \
            -i http://1.2.3.4/sessionInformation/1/status | grep "Progress" | sed 's/["Progress":"      %]//g')
            echo -ne "Download ${progress} % finished.\r"
        done
        echo "Download finished."
    break
done

下面是使用“set -x”运行的脚本的输出:

+ progress=99
+ echo -ne 'Download 99 % finished.\r'
+ [[ running, != \t\e\r\m\i\n\a\t\e\d\ \r\e\g\u\l\a\r\l\y ]]
++ curl -s -u admin:admin -H Accept:application/json -X GET -i http://1.2.3.4/sessionInformation/1/status
++ grep Progress
++ sed 's/["Progress":"      %]//g'
+ progress=

我正在运行 MacOS Ventura 13.4.1 和 Bash 3.2.57(1)。

我尝试将整个事情包装在各种 if 语句和/或 while 循环中,但无论我读到什么作为下载完成和状态已更改的指示器,问题始终是空的 $progress 变量。 我也尝试使用 -z 检查$progress,但没有用。 我只想让循环发布进度,一旦下载完成,就可以继续执行任何操作,至少打印另一个提示,即它已经完成了。

bash macos 休息 while-loop macos-ventura

评论

0赞 Ed Morton 8/22/2023
在我看来,它被困在对线路的调用中 - 添加一个超时,看看是否有帮助。顺便说一句,你的代码有一个无限循环,因为循环内永远不会改变,你也不会退出它。curlprogress=$(curl -s ...while [[ $status != "terminated regularly" ]]; dostatusbreak
0赞 Nahuel Fouilleul 8/22/2023
状态在内部 while 循环中未被修改,因此应该永远循环,也许内部 while 可以通过 if 更改,并且应该在 fi 之前添加 continue(而不是 done)
0赞 Nahuel Fouilleul 8/22/2023
此外,grep + sed 可以更改为 和grep -Po '"Status":\s*"\K[^"]*'grep -Po '"Progress":\s*"\K[^"%]*'
0赞 Charles Duffy 8/22/2023
一般来说,使用语法不感知的工具以明确定义的格式(无论是 JSON、YAML 还是其他任何格式)从字符串中解析数据是一个令人头疼的严重问题,无论是对您还是对网络连接另一端的任何人来说。(我有一个客户在前世使用过这种手动滚动的“解析器”,它们只是令人头疼的来源;如果你得到一个格式化的数据结构,请使用一个真正的解析器——对于 JSON、XML、YAML 等——来解释它)。jqxmlstarletyq
2赞 Ed Morton 8/22/2023
@NahuelFouilleul 仅供参考是不可移植的(两者都需要 GNU grep ),而可以在每台 Unix 机器上使用任何 sed。每当您想组合 grep+sed 命令时,仅使用 sed 或切换到 awk 通常是比仅使用 grep 更好的选择。grep -Po-P-osed -n 's/.*"Status":"\([^"]*\).*/\1/p'

答: 暂无答案