如何在Shell脚本中提取Curl请求WebSocket接口的HTTP状态码
问题:Shell脚本中无法提取WebSocket请求的HTTP 101状态码
我用以下curl命令测试WebSocket接口,能正常看到返回的101状态码:
curl --insecure \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Sec-WebSocket-Version: 13" \ --header "Sec-WebSocket-Key: websocket" \ -v \ https://127.0.0.1:443/blackhole
执行后返回的关键内容:
< HTTP/1.1 101 Switching Protocols < Server: nginx/1.18.0 < Date: Wed, 05 Jul 2023 06:13:59 GMT < Connection: upgrade < Upgrade: websocket < Sec-WebSocket-Accept: qVby4apnn2tTYtB1nPPVYUn68gY=
单独执行下面的命令能正确输出101:
curl --insecure --no-buffer --header "Connection: Upgrade" --header "Upgrade: websocket" --header "Sec-WebSocket-Version: 13" --header "Sec-WebSocket-Key: websocket" -v -i https://127.0.0.1:443/blackhole | awk '/^HTTP/{print $2}'
但写入Shell脚本后,变量result和b均为空,脚本内容:
#!/bin/bash result=$(curl --insecure --no-buffer --header "Connection: Upgrade" --header "Upgrade: websocket" --header "Sec-WebSocket-Version: 13" --header "Sec-WebSocket-Key: websocket" -v -i --silent https://127.0.0.1:443/blackhole) #echo $result b=$(echo $result | awk '/^HTTP/{print $2}') echo $b if [[ "$b" =101 ]]; then echo "hello world" fi
原因分析
- 换行丢失导致匹配失败:使用
echo $result时,Shell会把变量中的换行符替换成空格,原本多行的响应头变成单行字符串,awk '/^HTTP/'无法匹配到行首的HTTP(此时HTTP处于字符串中间)。 - 参数组合干扰:脚本中添加了
--silent,同时保留了-v,-v的调试信息输出到标准错误(stderr),而$(...)仅捕获标准输出(stdout),虽然-i会把响应头输出到stdout,但后续处理时的换行丢失才是主要问题。 - 条件判断语法错误:
[[ "$b" =101 ]]缺少空格,正确写法应为[[ "$b" == "101" ]],否则Shell会将=101视为一个整体,无法正确判断。
解决方法
方法一:直接管道处理(推荐)
跳过变量存储,直接将curl的输出传给awk处理,避免换行丢失问题,同时去掉不需要的-v参数:
#!/bin/bash b=$(curl --insecure \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Sec-WebSocket-Version: 13" \ --header "Sec-WebSocket-Key: websocket" \ -i --silent \ https://127.0.0.1:443/blackhole | awk '/^HTTP/{print $2}') echo "$b" if [[ "$b" == "101" ]]; then echo "hello world" fi
方法二:保留变量并正确处理换行
如果必须先保存到变量,使用echo "$result"(带双引号)保留换行符:
#!/bin/bash result=$(curl --insecure \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Sec-WebSocket-Version: 13" \ --header "Sec-WebSocket-Key: websocket" \ -i --silent \ https://127.0.0.1:443/blackhole) b=$(echo "$result" | awk '/^HTTP/{print $2}') echo "$b" if [[ "$b" == "101" ]]; then echo "hello world" fi
方法三:添加超时确保curl退出
WebSocket升级后连接会保持,curl可能不会自动退出,添加--max-time设置超时时间,确保能捕获到输出:
#!/bin/bash b=$(curl --insecure \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Sec-WebSocket-Version: 13" \ --header "Sec-WebSocket-Key: websocket" \ -i --silent --max-time 2 \ https://127.0.0.1:443/blackhole | awk '/^HTTP/{print $2}') echo "$b" if [[ "$b" == "101" ]]; then echo "hello world" fi
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

