You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Bash网络重定向时读取文件描述符3为何会挂起?

使用Bash网络重定向发送HTTP请求时cat命令挂起的问题

我正在用Bash和网络重定向发送HTTP请求,脚本如下:

exec 3<> $initial_url
path="/webhdfs/v1$hdfs_target?user.name=hdfs&op=OPEN"
printf "GET $path HTTP/1.1
Host: $url:$port
Accept: */*

" >&3
echo toto
cat <&3
echo titi
exec 3<&

我已经正确接收到响应,但cat命令无限挂起。执行输出(通过Ctrl+C终止)如下:

$ time bash toto.sh
toto
HTTP/1.1 307 TEMPORARY_REDIRECT
Cache-Control: no-cache
Expires: Thu, 20 Jul 2023 12:29:41 GMT
Date: Thu, 20 Jul 2023 12:29:41 GMT
Pragma: no-cache
Expires: Thu, 20 Jul 2023 12:29:41 GMT
Date: Thu, 20 Jul 2023 12:29:41 GMT
Pragma: no-cache
X-FRAME-OPTIONS: SAMEORIGIN
Set-Cookie: hadoop.auth="redacted_for_SO"; Path=/; HttpOnly
Location: redacted_for_SO
Content-Type: application/octet-stream
Content-Length: 0



real    0m19.042s
user    0m0.124s
sys     0m0.733s

输出里已经包含了我需要的所有内容,但cat就是无法结束。请问:

  1. 为什么cat会挂起?它在等待什么?
  2. 如何在数据接收完成后避免其挂起?

问题解答

1. cat挂起的原因

cat <&3挂起的核心原因是:你通过exec 3<> $initial_url建立的是双向TCP长连接。HTTP/1.1默认启用Keep-Alive,服务器在返回完整响应(本次响应的Content-Length: 0说明没有响应体)后,不会主动关闭连接,而是保持连接等待后续请求复用。

而cat的逻辑是持续从指定文件描述符读取数据,直到遇到EOF(文件结束符)。由于服务器没关闭连接,文件描述符3的读端一直处于可读状态(没有EOF),所以cat会一直阻塞等待新数据,直到你手动终止脚本。

另外脚本最后一行的exec 3<&是语法错误,正确关闭双向连接的写法是exec 3<&- 3>&-,但这个错误不是导致挂起的直接原因——挂起发生在cat执行阶段,此时连接还未被处理。

2. 避免挂起的解决方法

方案一:强制关闭长连接

在HTTP请求头中添加Connection: close,明确告诉服务器返回响应后立即关闭连接。这样服务器发送完响应后会主动断开TCP连接,cat读取完所有数据后会收到EOF,自动退出:

exec 3<> $initial_url
path="/webhdfs/v1$hdfs_target?user.name=hdfs&op=OPEN"
printf "GET $path HTTP/1.1
Host: $url:$port
Accept: */*
Connection: close

" >&3
echo toto
cat <&3
echo titi
exec 3<&- 3>&-

方案二:按需读取并主动关闭连接

如果需要保留长连接,可在读取完所需响应内容后,手动关闭文件描述符的读端。比如可以用awk读取到响应头结束的空行后退出,再关闭连接:

exec 3<> $initial_url
path="/webhdfs/v1$hdfs_target?user.name=hdfs&op=OPEN"
printf "GET $path HTTP/1.1
Host: $url:$port
Accept: */*

" >&3
echo toto
# 读取到空行为止(响应头结束)
awk '/^$/ {exit} {print}' <&3
echo titi
exec 3<&- 3>&-

方案三:使用curl替代(更简洁可靠)

如果没有必须用Bash原生重定向的需求,直接用curl工具更省心——它会自动处理HTTP连接的建立、响应读取和连接关闭,无需手动管理文件描述符:

curl "http://$url:$port/webhdfs/v1$hdfs_target?user.name=hdfs&op=OPEN"

内容的提问来源于stack exchange,提问作者Itération 122442

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:33:12