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

时间:2020-12-01 03:53:54

Context: monitor a low-volume, intermittent stream from a program

When debugging some program, one sometimes have to monitor some output. When output is ascii, no problem, just run in terminal (the program itself, or nc if it uses a TCP or UDP interface, or cat /dev/somedevice, or socat ..., whatever).

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

Need: monitor a binary stream real-time... and half-solutions

But sometimes output is binary. One can pipe it into various incantations of od, hd, e.g. od -t d1 for decimal numbers, od -t a1 for augmented ascii display (explicit non-printable characters using printable ones), etc.

但有时输出是二进制的。人们可以把它管成各种各样的od,hd,例如, od -t d1表示十进制数字,od -t a1表示增强的ascii显示(显式不可打印的字符,使用可打印的字符),等等。

The trouble is: those buffer the input until they have a complete line to print (a line often fitting 16 input characters). So basically until the program sends 16 character, the monitoring does not show anything. When the stream is low volume and/or intermittent, this defeats the purpose of a real-time monitoring. Many protocols indeed only send a handful of bytes at a time.

麻烦的是:那些缓冲输入直到他们有一个完整的行来打印(一行通常适合16个输入字符)。所以基本上直到程序发送16个字符,监控才会显示任何内容。当流量低和/或间歇时,这违背了实时监控的目的。许多协议实际上一次只发送少量字节。

It would be nice to tell it "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".

如果你愿意,可以告诉它“ok缓冲输入,但是在打印之前不要等待延迟x,即使它不会填满一行”。

man od, man hd don't mention any related option.

男子od,男子高清不提任何相关的选择。

Non-solution

Heavy programs like wireshark are not really an option: they cover only part of the needs and are not combinable. I often do things like this:

像wireshark这样的重型程序并不是一个真正的选择:它们只涵盖部分需求而且不可组合。我经常做这样的事情:

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

This monitors the output, and each time I press enter in the terminal, injects the sequence "something". It works very well but terminal output is buffered by 16-byte chunks and thus delayed a lot.

这会监视输出,每次按下终端输入时,都会输入序列“something”。它运行良好,但终端输出由16字节块缓冲,因此延迟了很多。

Summary

How do you simply monitor binary output from a program without byte-alignment-dependent delay ?

如何简单地监视程序的二进制输出而不依赖于字节对齐的延迟?

2 个解决方案

#1


I don't know which distribution you're using, but check to see whether you have, or can install, most. From the manpage:

我不知道您正在使用哪个发行版,但请检查您是否拥有或可以安装最多。从联机帮助页:

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.#. @...

Not in the manpage, but essential for your task, is the keystroke F (N.B. upper-case), which puts most into 'tail mode'. In this mode, most updates whenever new input is present.

不在联机帮助页中,但对于您的任务至关重要的是击键F(N.B。大写),它将大多数放入“尾部模式”。在此模式下,只要有新输入,大多数都会更新。

On the downside, most can't be told to begin in tail mode, so you can't just pipe to its stdin (it will try to read it all before showing anything). So you'll need to

在缺点方面,大多数都不能被告知以尾部模式开始,所以你不能只是管道到它的标准输入(它会尝试在显示任何东西之前读取它)。所以你需要

<your_command>  >/tmp/output

in the background, or in its own terminal, as appropriate. Then

在适当的时候,在后台,或在自己的终端。然后

most -b /tmp/output

and press F.

然后按F.

#2


Here's the best thing I found so far, hope someone knows something better.

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

Use -w1 option in od, or one of the examples format strings in man hd that eats one byte at a time. Kind of works, though makes a column-based display, which does not use terminal area efficiently.

在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"'

This displays thing like this:

这显示如下:

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_

The good thing is one can configure it to their context and taste:

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

{ 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"'

This displays thing like this:

这显示如下:

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_

But still, a regular hd display would use screen area more efficiently:

但是,常规的高清显示器会更有效地使用屏幕区域:

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.(..|

#1


I don't know which distribution you're using, but check to see whether you have, or can install, most. From the manpage:

我不知道您正在使用哪个发行版,但请检查您是否拥有或可以安装最多。从联机帮助页:

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.#. @...

Not in the manpage, but essential for your task, is the keystroke F (N.B. upper-case), which puts most into 'tail mode'. In this mode, most updates whenever new input is present.

不在联机帮助页中,但对于您的任务至关重要的是击键F(N.B。大写),它将大多数放入“尾部模式”。在此模式下,只要有新输入,大多数都会更新。

On the downside, most can't be told to begin in tail mode, so you can't just pipe to its stdin (it will try to read it all before showing anything). So you'll need to

在缺点方面,大多数都不能被告知以尾部模式开始,所以你不能只是管道到它的标准输入(它会尝试在显示任何东西之前读取它)。所以你需要

<your_command>  >/tmp/output

in the background, or in its own terminal, as appropriate. Then

在适当的时候,在后台,或在自己的终端。然后

most -b /tmp/output

and press F.

然后按F.

#2


Here's the best thing I found so far, hope someone knows something better.

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

Use -w1 option in od, or one of the examples format strings in man hd that eats one byte at a time. Kind of works, though makes a column-based display, which does not use terminal area efficiently.

在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"'

This displays thing like this:

这显示如下:

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_

The good thing is one can configure it to their context and taste:

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

{ 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"'

This displays thing like this:

这显示如下:

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_

But still, a regular hd display would use screen area more efficiently:

但是,常规的高清显示器会更有效地使用屏幕区域:

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.(..|