间歇性二进制数据的实时监控

Real-time monitoring of intermittent binary data

上下文:监视来自程序的低音量、间歇性流

调试某些程序时,有时需要监视某些输出。当输出为 ascii 时,没问题,只需在终端中 运行(程序本身,或 nc,如果它使用 TCP 或 UDP 接口,或 cat /dev/somedevice,或 socat ...,任何)。

需要:实时监控二进制流...和半解

但有时输出是二进制的。可以将其管道化为 odhd 的各种咒语,例如od -t d1 用于十进制数,od -t a1 用于增强的 ascii 显示(显式不可打印字符使用可打印字符)等。

问题是:那些缓冲输入直到他们有完整的行要打印(一行通常适合 16 个输入字符)。所以基本上直到程序发送了16个字符,监控才显示什么。当流是低音量 and/or 间歇性时,这就违背了实时监控的目的。许多协议确实一次只发送少量字节。

说出来就好了"ok buffer the input if you wish, but don't wait more than delay x before printing it, even if it won't fill one line".

man od,man hd不要提及任何相关选项。

无解

像 wireshark 这样的繁重的程序并不是真正的选择:它们只满足部分需求并且不可组合。我经常这样做:

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | od -t d1

这会监视输出,每次我在终端中按回车键时,都会注入序列 "something"。它工作得很好,但终端输出由 16 字节块缓冲,因此延迟很多。

总结

如何在没有字节对齐相关延迟的情况下简单地监视程序的二进制输出?

这是我迄今为止发现的最好的东西,希望有人知道更好的东西。

使用 od 中的 -w1 选项,或 man hd 中的示例格式字符串之一,一次吃一个字节。有点工作,虽然制作了基于列的显示,但没有有效地使用终端区域。

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | hexdump -v  -e '/1  "%_ad#  "' -e '/1 " _%_u\_\n"'

这显示如下:

0#   _nul_  (plenty of wasted space on the right... )
1#   _1_    (no overview of what's happening...)
2#   _R_
3#   _ _
4#   _+_
5#   _D_
6#   _w_
7#   _d8_
8#   _ht_
9#   _nak_

好处是可以根据自己的背景和品味配置它:

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | hexdump -v  -e '/1  "%_ad#    "' -e '/1    "%02X "' -e '/1 " _%_u\_\n"'

这显示如下:

0#    6B  _k_
1#    21  _!_
2#    F6  _f6_
3#    7D  _}_
4#    07  _bel_
5#    07  _bel_
6#    60  _`_
7#    CA  _ca_
8#    CC  _cc_
9#    AB  _ab_

但是,常规 hd 显示器仍然可以更有效地使用屏幕区域:

hd

00000000  f2 76 5d 82 db b6 88 1b  43 bf dd ab 53 cb e9 19  |.v].....C...S...|
00000010  3b a8 12 01 3c 3b 7a 18  b1 c0 ef 76 ce 28 01 07  |;...<;z....v.(..|

我不知道您使用的是哪个发行版,但请检查您是否拥有或可以安装 most。来自联机帮助页:

OPTIONS
   -b     Binary mode.  Use this switch when  you  want
          to  view  files  containing 8 bit characters.
          most will display the file 16 bytes per  line
          in  hexadecimal  notation.   A  typical  line
          looks like:

               01000000 40001575 9C23A020 4000168D     ....@..u.#. @...

          When used with the -v option, the  same  line
          looks like:

               ^A^@^@^@  @^@^U u 9C #A0    @^@^V8D     ....@..u.#. @...

按键 F(N.B。大写)不在联机帮助页中,但对您的任务必不可少,它将 most 放入 'tail mode'。在此模式下,只要有新输入出现,most 就会更新。

不利的一面是,most 不能被告知以尾模式开始,因此您不能直接通过管道传输到它的 stdin(它会在显示任何内容之前尝试读取所有内容).所以你需要

<your_command>  >/tmp/output

在后台,或在其自己的终端中,视情况而定。那么

most -b /tmp/output

然后按 F