为何Bash脚本中Curl在主机不存在时不返回状态码?
问题
在Linux Bash脚本中使用curl调用Web服务,仅需获取HTTP状态码、无需响应内容,脚本开启了set -euo pipefail严格模式:
#!/bin/bash set -euo pipefail # put bash in "strict mode" echo "Before" response2=$(curl -o /dev/null -s -w '%{http_code}' -u username:password-X POST https://xxxxx.yyyyy.at:8081/MyPath/service/rest/crypto/encrypt -H 'Content-Type: application/json' -d '{"deviceId": "ABCD","payload": "ABCD"}') echo "after"
- 请求有效时,脚本正常输出
200; - 服务路径错误时,返回
500; - 但主机不存在时,仅输出
Before...后脚本直接终止,无法获取000状态码,而手动执行相同curl命令能正常返回000。
可复现示例:
#!/bin/bash set -euo pipefail #- Check kms f_check_kms(){ echo "Before..." response2=$(curl -o /dev/null -s -w '%{http_code}' -u user:xxxx -X POST https://xxxx.xxx.intra.graz.at:8081/ATM-KeyManagement-REST-Service/service/rest/crypto/encryptUCast -H 'Content-Type: application/json' -d '{"deviceId": "SAG0530000016261", "encryptionSuite": "DLMS_SUITE_0", "securityMode": "AUTHENT_AND_ENCRYPT", "roleId": "001","initialVector": "4D4D4D0000BC614E01234567","payload": "ABCD","usedGuek":"NO","usedGak":"NO"}') echo "$response2" } f_check_kms
原因分析
问题核心在于你开启的set -e选项:
set -e会让Bash脚本在任何命令返回非零退出码时直接终止执行,不会继续运行后续代码。- 当主机不存在时,curl无法建立连接,会返回非零退出码(比如退出码6,表示无法解析主机地址),此时
set -e触发,脚本直接终止,后续的echo "$response2"根本没有执行机会。 - 手动执行curl时,没有开启
set -e,即使curl返回非零退出码,shell也会继续执行,所以你能看到curl输出的000状态码。 - 另外,
$(...)捕获的是命令的标准输出,但如果命令因为set -e提前终止,变量赋值操作也无法完成,脚本直接退出后自然无法输出结果。
内容的提问来源于stack exchange,提问作者MichaelW
相关产品推荐
相关产品推荐

