适用场景
你用 curl 检查网页或下载一个业务接口的响应,网站已经返回不存在的页面,脚本却仍然记录成功。这通常源于两个不同层面的结果被混在一起:HTTP 状态码描述服务器如何处理请求,curl 退出码描述命令执行结果。
本文在 Linux 的 Bash 终端中发起单次、只读的 HTTPS 请求,保存响应证据,并演示如何让常见 HTTP 错误反映到退出码。请选择自己管理或已获准检查的地址,不需要登录信息,也不需要添加认证头。
原理:收到错误页面也可能完成了传输
服务器返回 404 时,仍然可能正常发送响应头和一段说明文字。默认情况下,curl 可以认为这次收发顺利完成,因此退出码为零。curl 项目的HTTP 响应说明专门解释了这种行为。
通常,2xx 表示请求成功,3xx 涉及重定向等进一步处理,4xx 表示请求无法按客户端意图处理,5xx 表示服务器处理失败。这些类别的标准含义见 RFC 9110。即使得到 200,也仍需结合接口约定判断业务内容是否正确。
准备工作
准备 curl 7.76.0 或更高版本,以便使用保留错误正文的检测选项。先查看当前版本:
curl --version
本文所有代码块应在同一个 Bash 会话中顺序执行。输入地址时使用实际 HTTPS URL,避免包含个人令牌、签名参数或其他敏感信息。若要比较成功与失败情况,应选择一个正常页面,以及自己能够确认会返回 404 的测试地址;不能假定任意随机路径都会返回 404。
分步骤操作
第一步:创建独立结果目录
work_dir=$(mktemp -d)
read -r -p '输入已获准检查的 HTTPS URL:' target_url
printf '结果目录:%s\n' "$work_dir"
work_dir 保存本次结果目录路径,target_url 保存你输入的实际地址。每次新建目录可以减少旧文件干扰,也避免覆盖之前保存的响应。这里没有更改系统网络或服务器设置。
第二步:观察默认行为
if curl --silent --show-error \
--connect-timeout 5 --max-time 20 \
--dump-header "$work_dir/default.headers" \
--output "$work_dir/default.body" \
--write-out 'http_code=%{http_code}\n' \
"$target_url" > "$work_dir/default.status"; then
default_rc=0
else
default_rc=$?
fi
printf 'curl_exit=%s\n' "$default_rc"
cat "$work_dir/default.status"
连接时限用于限制连接阶段等待,总时限限制整个操作。响应头、响应正文和状态输出分别保存,便于检查。静默选项隐藏进度条,显示错误选项保留失败提示。
如果目标实际返回 404,且传输没有其他错误,此时可能看到 HTTP 状态码为 404,而退出码为零。应以现场输出为准,不能预先假定网站一定返回哪种结果。
第三步:让 HTTP 错误影响退出码
if curl --silent --show-error --fail-with-body \
--connect-timeout 5 --max-time 20 \
--dump-header "$work_dir/checked.headers" \
--output "$work_dir/checked.body" \
--write-out 'http_code=%{http_code}\n' \
"$target_url" > "$work_dir/checked.status"; then
checked_rc=0
else
checked_rc=$?
fi
printf 'curl_exit=%s\n' "$checked_rc"
cat "$work_dir/checked.status"
新增选项让 HTTP 状态码达到 400 或以上时产生错误退出码,并保留响应正文,常见对应退出码是 22。它与不保留错误正文的失败检测选项互斥,不能同时使用。版本要求和参数行为可查阅 curl 官方手册。
验证方法
分别使用正常页面与已知的不存在页面执行流程,核对状态文件和退出码。正常响应在传输完成时通常得到退出码零;已知 404 在启用检测后应体现为失败,同时可以打开保存的正文了解服务器返回的说明。
如果没有收到有效 HTTP 响应,状态输出可能显示 000。它是 curl 在这种情况下的输出表示,不是服务器发出的标准 HTTP 状态码。此时应结合终端错误和退出码继续检查解析、连接或证书问题。
两次请求之间服务器状态可能变化,所以比较时还应检查各自保存的响应头。不要因为两个文件正文不同,就立即认为是检测参数改变了服务器行为。
常见错误
退出码必须及时保存。如果先执行打印、读取文件或其他命令,再读取上一条命令的退出状态,得到的可能已经不是 curl 的结果。示例使用条件分支立即保存,便于放入启用了严格错误处理的脚本中。
重定向也需要单独理解:本文没有自动跟随跳转,3xx 通常不会被该失败检测选项判为错误。如果业务要求必须得到 200,应在保存结果后显式检查状态值,而不能仅接受退出码零。
此外,某些网站会用 200 返回“页面不存在”或“服务不可用”的文字。HTTP 层检查无法识别所有业务失败,需要按接口约定核对正文。旧版 curl 不认识该选项时,应通过发行版支持的方式升级,或采用经过核对的状态码判断逻辑。
安全与回退
本流程只发出读取请求并创建本地结果文件,无需修改服务器,也没有系统网络配置需要回退。检查完成后,核对打印出的目录路径,再通过文件管理器清理本次结果。
响应头可能包含会话相关字段,正文也可能带业务信息。对外提交排查材料前应先审阅内容。遇到证书校验失败时,应修复时间、信任链或服务配置,保留校验机制,避免把跳过校验误当作巡检成功。
参考资料与转载说明
本文依据上述公开资料进行中文原创整理,不是逐句翻译,也不替代厂商手册。操作前请核对自己的版本、型号和备份。
评论一下?