网站返回 404 为何脚本仍报成功:用 curl 同时记录状态码和退出码

2026-11-1 / 0 评论 / 0 阅读

网站返回 404 为何脚本仍报成功:用 curl 同时记录状态码和退出码 教程示意图

适用场景

你用 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 不认识该选项时,应通过发行版支持的方式升级,或采用经过核对的状态码判断逻辑。

安全与回退

本流程只发出读取请求并创建本地结果文件,无需修改服务器,也没有系统网络配置需要回退。检查完成后,核对打印出的目录路径,再通过文件管理器清理本次结果。

响应头可能包含会话相关字段,正文也可能带业务信息。对外提交排查材料前应先审阅内容。遇到证书校验失败时,应修复时间、信任链或服务配置,保留校验机制,避免把跳过校验误当作巡检成功。

参考资料与转载说明

本文依据上述公开资料进行中文原创整理,不是逐句翻译,也不替代厂商手册。操作前请核对自己的版本、型号和备份。

评论一下?

OωO
取消