调试某些程序时,有时需要监视某些输出。当输出为ascii时,没问题,只需在终端(程序本身,或nc
,如果它使用TCP或UDP接口,或cat /dev/somedevice
,或socat ...
,无论如何)运行。
但有时输出是二进制的。可以将其管道化为od
,hd
的各种咒语,例如od -t d1
表示十进制数字,od -t a1
表示增强的ascii显示(使用可打印字符的显式不可打印字符)等。
麻烦在于:那些缓冲输入直到它们有一条完整的行来打印(一条线通常适合16个输入字符)。所以基本上直到程序发送16个字符,监控才会显示任何内容。当流量低和/或间歇时,这违背了实时监控的目的。许多协议实际上一次只发送少量字节。
很高兴告诉它"如果你愿意,可以缓冲输入,但是在打印之前不要等待超过延迟x,即使它不会填满一行&#34 ;
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
这会监视输出,每次按下终端输入时,都会输入序列""。它运行良好,但终端输出由16字节块缓冲,因此延迟很多。
如何简单地监视程序的二进制输出而不依赖于字节对齐的延迟?
答案 0 :(得分:1)
我不知道您正在使用哪个发行版,但请检查您是否拥有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
不在联机帮助页中,但对您的任务至关重要的是按键most
(N.B。大写),它将most
置于尾部模式'。在此模式下,只要有新输入,most
就会更新。
在缺点方面,stdin
无法告知以尾部模式开始,因此您无法管道到其<your_command> >/tmp/output
(它会尝试先阅读它显示任何东西)。所以你需要
most -b /tmp/output
在后台,或在其自己的终端中,视情况而定。然后
F
并按 public void importPlug() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
File jar = new File ("/home/karim/Downloads/yarab/VideoPlugin.jar");
JarFile jf = new JarFile(jar);
ArrayList <URL> urls = new ArrayList<URL>();
urls.add(jar.toURI().toURL());
java.util.jar.Manifest mf = jf.getManifest();
if (mf != null) {
String cp =
((java.util.jar.Manifest) mf).getMainAttributes().getValue("class-path");
if (cp !=
null) {
for (String cpe : cp.split("\\s+")) {
File lib =
new File(jar.getParentFile(), cpe);
urls.add(lib.toURI().toURL());
}
}
}
for (URL u : urls) {
System.out.println(u.toString());
}
ClassLoader cl =
new URLClassLoader(urls.toArray(new URL[urls.size()]), PluginInterface.class.getClassLoader());
//Class c = cl.loadClass("VideoPlugin");
Class c = Class.forName("selenium.VideoPlugin", true, cl);
pi = (PluginInterface) c.newInstance();
}
。
答案 1 :(得分:0)
这是迄今为止我发现的最好的事情,希望有人知道更好的事情。
在-w1
中使用od
选项,或者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.(..|