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

如何在Bash中逐行读取含空字节的stdin并保留空字节?

解决Bash读取含空字节的WebSocket消息问题

Bash的read命令天然无法处理包含空字节的输入——因为Bash变量本质是C风格字符串(以空字节结尾),不仅存不了带空字节的数据,read遇到空字节还会直接截断输入。结合你用websocketd处理Protobuf消息的场景,有两种可行方案:

方案一:直接通过管道传递原始数据(不存变量)

既然管道可以完整保留空字节,我们可以绕过read,直接把每行的原始消息数据传给protoc。用工具读取完整的行(包括空字节)后直接转递:

用GNU dd实现(精准控制行分隔)

while :; do
  # 读取直到换行符(每条WebSocket消息的分隔符),最多读取10MB(可根据消息大小调整)
  dd bs=1 delimiter=$'\n' count=$((1024*1024)) 2>/dev/null | protoc --decode=你的消息类型 你的proto文件.proto
done

dd的delimiter=$'\n'会一直读取到换行符为止,中间的空字节会完整保留,直接传给protoc解码。

用head实现(简洁高效,依赖GNU head)

while :; do
  # head -n1会读取到第一个换行符,不管中间有没有空字节
  head -n1 | protoc --decode=你的消息类型 你的proto文件.proto
done

方案二:转码为Base64/十六进制后存储,解码再传递

如果必须把消息暂存到变量,可以先将原始数据转成无空字节的文本格式(Base64或十六进制),读取后再解码恢复原始数据:

Base64转码方案

while :; do
  # 将含空字节的行转成Base64(纯文本,可安全存变量)
  msg_base64=$(head -n1 | base64)
  # 解码回原始数据,传给protoc
  echo "$msg_base64" | base64 -d | protoc --decode=你的消息类型 你的proto文件.proto
done

十六进制转码方案(用xxd工具)

while :; do
  # 将含空字节的行转成纯十六进制字符串
  msg_hex=$(head -n1 | xxd -p)
  # 解码回原始数据,传给protoc
  echo "$msg_hex" | xxd -p -r | protoc --decode=你的消息类型 你的proto文件.proto
done

内容的提问来源于stack exchange,提问作者LuisAFK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:34:55