我已经跟踪了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 \ rn \ 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\377
y \ 10 \ r \ 21 \ ftransl!N \ 2ble%\ 1ca!a \ 340 \ 3Q \ 0 \ 1 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
\ 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 \ 6 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*
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\0d
Y \ 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 _ \ 240 \ 363 \ 2 \ 1 \ 16 \ 25 \ 340 \ 3 \ 16 \ r \ 0 \ 21 \ vmultipliers \223\340\0'AC\4sourc\202\202\340\3\27\0\v\200\27\0_C\326\340\0074\1\16\21
\ 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钩子\ 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 \31\0- \223\1\21\t\341\0\30B-\0\1!\10\0003a\253\0005
C \ 340 \ 0a!\ 312 \ 1 \否\ 300#\ 240!&\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\7
\ 320 \ 0 \ 342 \ 3XAz \ v \ 16> \ 16G \ 16?\ 16 @ \ 16A \ 21 \ 30 \ 341 \ tT \ 201 \ 5 \ 1 \ 21 \ 22 \ 200 \ 243 \ 0 B0 \ 6字符串#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表示。
我试图通过}\241\237\0\0\242e\341\4n\5\16;\24\10\16< \7\2=\21\35\340\1m\0
在shell中解码它们,例如:
while read line; do printf "%s" "$line"; done < <(cat strace.log | head -n2)
但失败了(看起来没有任何意义):
printf
30 @ 6216rr n4tatus @ 04213int 11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240rn257202v0?00022710stdClass247213cid216schema214d37ata25n247215block246216fields24f213bid2425214type 037erial2110not null5216module244167217va37rchar216length6@16t5217defaultr215de2lta@516v16f6 35716r210010215t 207C
27300,171623162421nvisibility340t3475pages242 20534tex @ 206 2611it 36505240 /760214size 222finy216weight243 ;022300 66region@83405P5custom
y10r21ftransl!N2ble%1ca!a3403Q01 0377
25205!$ 0n 3341223016340016A2142213r!354 @ 10 @ v222110un p516#16 $ 21f200l241b @ n24166 n31vprimary key2416016621vunique@21ts241213tmd243 31020 2vn621616217index 210101214list24524036021 3610266316256416n 164214name 70na3172_ro
y0 225a; 2402012'21van0_ 2130n 213016 l6%16!24116%
200251613400U = @ U1163 @ 222 2122lob @ On2316)216expire @ 303420267217create24117 M21016&@E4214bod201_53216t41623B\2g1634 303info .07a2550200@q!L56forma201332B/!d241637 y0*
Y022 30555small240!a320.`2300.240240012402403,21vb S2kpo!3132 ..
有没有更好的方法来解析207
命令的输出以查看传递给< 250n2031"1770d
/ strace
的纯字符串?
理想情况下,可以打印包括换行符(recvfrom
)在内的可打印字符,但是要切断NULL和其他不可打印的字符? 最佳答案
为什么read
不起作用的问题,因为shell已经在转义字符,所以字符串被加倍转义,因此\r\n
被打印为rn
。
对于ignore escaping of characters by shell,您可以使用read -r
允许反斜杠转义任何字符(因此将它们按字面意义处理)。这是示例:
while read -r line; do printf "%b\n" "$line"; done < strace.log | strings
由于它是二进制数据,因此上面的示例还包括strings
命令,以仅显示可打印的字符串。
当指定-x
时,Strace还支持以十六进制打印所有字符串,但是它的工作原理相同。
这是实时解析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"
)的完整示例如下所示:
strace -e trace=read,write,recvfrom,sendto -s 1000 -fp $(pgrep -n php) 2>&1 | format-strace
检查类似的示例:Unix.SE上的How to view the output of a running process in another bash session?