如何将shell中的strace解析为纯文本?

时间:2016-04-11 18:58:33

标签: shell parsing escaping strace

我跟踪strace命令生成的日志,就像运行PHP一样:

sudo strace -e sendto -fp $(pgrep -n php) -o strace.log

输出如下:

  

11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240\r\n\257\202\v\0?\0\0\0\2\27\10stdClass\24\7\21\3cid\21\6schema\21\4d\37ata\25\n\247\21\5block\24\6\21\6fields\24\f\21\3bid\24\2\5\21\4type 0\37erial\21\10not null\5\21\6module\24\4\16\7\21\7va\37rchar\21\6length\6@\16\t\5\21\7default\r\21\5de\2lta@\5\16\v\16\f\6 \35\7\16\r\21\0010\21\5t \207C\30@6\2\16\r\r n\4tatus@0\4\21\3int/\7\6\0\21\4size \222\finy\21\6weight\24\3 ;\0\22\300 \6\6region@8\340\5P\5custom\27\300,\17\16\23\16\24\21\nvisibility\340\t\34\7\5pages\24\2 \205\3\4tex@\206 \261\1it \365\0\5\240\0\377y\10\r\21\ftransl!N\2ble %\1ca!a\340\3Q\0\1n\31\vprimary key\24\1\6\0\16\6\21\vunique@\21\ts\24\1\21\3tmd\24\3 \31\0\20 2\v\n\6\2\16\16\21\7index \210\10\1\21\4list\24\5\240\36\0\21 \36\10\26\6\3\16\25\6\4\16\n \1\6\4\21\4name \7\0\na\317\2_ro\252\0\5!$\0\n \3\341\2\23\0\16\340\0\16A\214\2\21\3r!\354@ \v\22\21\10unsigned\5@\332\0\36\213\0\n \213\0\16 l\6%\16!\24\1\16%\271\0%@p\5\16#\16$\21\f\200l\241b@n\2\4\16\6M\2\10\16&@E\4\21\4bod\201_\5\32\16\t\4\16\23B\\\2g\16\34 \30\3info .\0\7a\255\0\200@q!L\5\6forma\201\332B/!d\2\4\16\37 y\0*y\0 \225a;\240\201\2'\21\van\0_\207\200\2\5\16\1\340\0U =@U\1\16\3@\222 \212\2lob@O\n\23\16)\21\6expire@\30\342\0\26\7\21\7create\241\17< \25\0\n\203\1\"\177\0dY\0\22 \305\5\5small\240!a\32\0.\230\0.\240\240\0\1\240\240\3,\21\vb S\2kpo\"\313\2s\24\6!\220\2\t\21\2\241q\0\10 ?\4\21\tno \213\6ort\5\21\fm\";\3ine_A\313\232\241\3\2\5\16#\340\4\16!\345\340\0U\223\340\0'AC\4sourc\202\202\340\3\27\0\v\200\27\0_C\326\340\0074\1\16\21_\240\363\2\1\16\25\340\3\16\r\0\21\vmultipliers\31\0- \223\1\21\t\341\0\30B-\0\1!\10\0003a\253\0005\v\0005ac \327Dz\"\364 \20\0\10 \6\0 @\333\r\0165\16\36\0163\21\nidenti$x\nr\0166\21\vadmin_ce\10\21\5label\21\f\244H\6 hook\21\23\240\r\0_\340\1\375\fs\21\3api\24\4\21\5own F\0062\16C\16B\21\17 H\5imum_v \260$\25\7\6\1\21\17curr m\340\1\22!\242\0002\"\305\0022\21\20\340\1N\5_groupa\247\2\6\0163\352\0\10 \352\2\0164\5 \325C%\341\0P\341\5\220\1\0162aQA\26\4\16:\5\21\17\201\321\1 c\"$\5back\21#\340\7b\0_\200!\340\3\311\1\16\7C\340\0a!\312\1\no \300#\240!&}\241\237\0\0\242e\341\4n\5\16;\24\10\16< \7\2=\21\35\340\1m\0\320\0 \342\3XAz\v\16>\16G\16?\16@\16A\21\30\341\tT\201\5\1\21\22\200\243\0 B0\6 string#o\4toolsbD\1\16C \260\0D!D\4C\16L\16E!P\0F \3\201T\16G\21\21ckeditor_set%\266\0gE\323\0\5%Q\0# 4@\345!)\"w#\372\1\21\10\340\0!\0\1 \31\0\32\240\334\4#\16\n\21\10\300D \r\2O\21\25\300\r\6_input_\244+\340\16V\1\16+ \31\340\4h X\0\2!;\0# \245\0+ \247\0Q T\7R\21\26comme#/\0_%\266\2cko W\3pane ;\4\5\24\10\21\7@\v\0_\243\257\301\231\1\21\4F\35 !\340\1\22F\323\0021\21\10\"\311'B\0e@\223A\254&f`\346\"~\6\vcollap&q%\227\340\6\35\2\0\21\t\240\35\344\1a\3009\0\0#\212\300.\0001\200L$\247\1enFl\344\0\216\300,\0\1G\5\3view\340\0002\300\177 \372\0\1 K\0T!"..., 8196, MSG_NOSIGNAL|MSG_MORE, NULL, 0) = 8196

听起来这些都是普通的C escape codes

我试图通过C在shell中解码它们,如:

/\7\6\0\21\4size \222\finy\21\6weight\24\3 ;\0\22\300 \6\6region@8\340\5P\5custom

但它失败了(看起来没有任何意义):

  

\0\377

有没有更好的方法来解析n\31\vprimary key\24\1\6\0\16\6\21\vunique@\21\ts\24\1\21\3tmd\24\3 \31\0\20 2\v\n\6\2\16\16\21\7index \210\10\1\21\4list\24\5\240\36\0\21 \36\10\26\6\3\16\25\6\4\16\n \1\6\4\21\4name \7\0\na\317\2_ro命令的输出,看看传递给\213\0\n \213\0\16 l\6%\16!\24\1\16% / M\2\10\16&@E\4\21\4bod\201_\5\32\16\t\4\16\23B\\\2g\16\34 \30\3info .\0\7a\255\0\200@q!L\5\6forma\201\332B/!d\2\4\16\37 y\0*的普通字符串?

理想情况下,可以打印包括新行(\207)在内的可打印字符,但截断NULL和其他不可打印的字符?

1 个答案:

答案 0 :(得分:5)

string copiedCutText = YourMethod(); if (rdbPasteBeginning.Checked) { rtbMain.Text = copiedCutText + rtbMain.Text; } else { rtbMain.Text += copiedCutText; } 无效的问题,因为shell已经转义字符,因此字符串被转义为双倍,因此read打印为\r\n

ignore escaping of characters by shell,您可以使用rn允许反斜杠转义任何字符(因此它们会被字面处理)。这是一个例子:

read -r

由于它是二进制数据,上面的例子还包括while read -r line; do printf "%b\n" "$line"; done < strace.log | strings 命令,只显示可打印的字符串。

当指定strings时,Strace还支持以十六进制打印所有字符串,但它的工作方式相同。

以下是实时解析-x输出的版本:

strace

更多while read -r line; do printf "%b\n" "$line" | strings done < <(sudo strace -e recvfrom,sendto -s 1000 -fp $(pgrep -n php) 2>/dev/stdout) 可以使用strings替换为更具体的过滤器,以获取双引号内的内容:

grep

然而,这仍然可以打印二进制格式。

为避免这种情况,让我们简化整个过程,因此我们定义以下格式化程序别名:

grep -o '".\+[^"]"' | grep -o '[^"]\+[^"]'

其中:

  • alias format-strace='grep --line-buffered -o '\''".\+[^"]"'\'' | grep --line-buffered -o '\''[^"]*[^"]'\'' | while read -r line; do printf "%b" $line; done | tr "\r\n" "\275\276" | tr -d "[:cntrl:]" | tr "\275\276" "\r\n"' - 选择带引号的双引号字符串
  • grep -o '".\+[^"]"' - 在双引号中选择文字
  • grep -o '[^"]*[^"]' - 将每一行存储到while read -r line$line一些操作(do
  • help read - 通过扩展反斜杠转义序列打印行
  • printf "%b" $line - 暂时将tr "\r\n" "\275\276"替换为\r\n
  • \275\276 - 删除所有控制字符
  • tr -d "[:cntrl:]" - 恢复新的行结尾

然后跟踪某些命令(例如tr "\275\276" "\r\n")的完整示例可能如下所示:

php

在Unix.SE

检查类似示例:How to view the output of a running process in another bash session?