如何将shell中的strace解析为纯文本?
How to parse strace in shell into plain text?
我跟踪了 strace
命令生成的日志,例如在 运行 PHP 上由:
sudo strace -e sendto -fp $(pgrep -n php) -o strace.log
输出如下:
11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240\r\n72\v[=40=]?[=40=][=40=][=40=]stdClasscidschemadata\n7blockfields\fbidtype 0erialnot nullmodulevarcharlength@\tdefault\rdelta@<em>\v\f \r[=40=]10t 7<code>C
@6\r\r ntatus@0int/[=15=]size 2\finyweight ;[=15=]0 region@80Pcustom
0,\nvisibility0\tpages 5tex@6 1it 5[=40=]0[=16=]7
y\r\ftransl!Nble %ca!a0Q[=40=]n\vprimary key[=17=]\vunique@\tstmd [=17=] 2\v\nindex 0list0[=17=] \n name [=17=]\na7_ro
2[=40=]!$[=40=]\n 1[=40=]0[=40=]A4r!4@ \vunsigned@2[=40=]3[=18=]\n 3[=18=] l%!%
1[=40=]%@p#$\f0l1b@nM&@Ebod1_\tB\g info .[=19=]a5[=19=]0@q!Lforma12B/!d y[=19=]*
y[=40=] 5a;01'\van[=40=]_7
00[=40=]U =@U@2 2lob@O\n)expire@2[=40=]create1< [=21=]\n3\"7[=21=]d
Y[=40=] 5small0!a[=40=].0[=22=].00[=22=]00,\vb Skpo\"3s!0\t1q[=22=] ?\tno 3ort\fm\";ine_A3
21#0!50[=40=]U30[=23=]'ACsourc220[=23=]\v0[=23=]_C60[=23=]74
_030\r[=40=]\vmultipliers[=24=]- 3\t1[=24=]B-[=24=]![=24=]03a3[=24=]05
\v[=40=]05ac 7Dz\"4 [=40=] [=40=] @3\r6563\nidenti$x\nr66\vadmin_celabel\f4H hook0\r[=40=]_05\fsapiown F[=40=]62CB Himum_v 0$curr m0!2[=40=]02\"5[=40=]220N_groupa7632[=25=] 264 5C%1[=25=]P1062aQA:11 c\"$back#0b[=25=]_0!01
C0[=40=]a!2\no 0#0!&}17[=26=][=26=]2e1n;< =0m[=26=]
0[=40=] 2XAz\v>G?@A1\tT103[=40=] B0 string#otoolsbDC 0[=40=]D!DCLE!P[=40=]F 1TGckeditor_set%6[=40=]gE3[=40=]%Q[=40=]# 4@5!)\"w#20[=40=]![=40=] [=40=]04#\n0D \rO0\r_input_4+0V+ 0h X[=40=]!;[=40=]# 5[=40=]+ 7[=40=]Q TRcomme#/[=40=]_%6cko Wpane ;@\v[=40=]_3711F !0F3[=40=]21\"1'B[=40=]e@3A4&f`6\"~\vcollap&q%70[=40=]\t04a09[=40=][=40=]#20.[=40=]010L$7enFl4[=40=]60,[=40=]Gview0[=40=]0207 2[=40=] K[=40=]T!"..., 8196, MSG_NOSIGNAL|MSG_MORE, NULL, 0) = 8196
听起来这些都是普通的C escape codes。
我试图通过 printf
在 shell 中解码它们,例如:
while read line; do printf "%s" "$line"; done < <(cat strace.log | head -n2)
但是失败了(貌似没有任何意义):
11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240rn257202v0?00022710stdClass247213cid216schema214d37ata25n247215block246216fields24f213bid2425214type 037erial2110not null5216module244167217va37rchar216length6@16t5217defaultr215de2lta@<em>516v16f6 35716r210010215t 207<code>C
30@6216rr n4tatus@04213int/760214size 222finy216weight243 ;022300 66region@83405P5custom
27300,171623162421nvisibility340t3475pages242 20534tex@206 2611it 365052400377
y10r21ftransl!N2ble %1ca!a3403Q01n31vprimary key2416016621vunique@21ts241213tmd243 31020 2vn621616217index 210101214list24524036021 3610266316256416n 164214name 70na3172_ro
25205![=41=]n 3341223016340016A2142213r!354@ v222110unsigned5@3320362130n 213016 l6%16!24116%
2710%@p516#16f200l241b@n24166M21016&@E4214bod201_53216t41623Bg1634 303info .07a2550200@q!L56forma201332B/!d241637 y0*
y0 225a;2402012'21van0_207
200251613400U =@U1163@222 2122lob@On2316)216expire@303420267217create24117< 250n2031"1770d
Y022 30555small240!a320.`2300.240240012402403,21vb S2kpo"3132s246!2202t212241q010...
是否有更好的方法来解析 strace
命令的输出以查看传递给 recvfrom
/sendto
的纯字符串?
理想情况下,可以打印包括换行符在内的可打印字符 (\r\n
),但会截断 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" "56" | tr -d "[:cntrl:]" | tr "56" "\r\n"'
其中:
grep -o '".\+[^"]"'
- select 带引号的双引号字符串
grep -o '[^"]*[^"]'
- select 双引号内的文字
while read -r line
- 将每一行存储到 $line
和 do
一些动作中 (help read
)
printf "%b" $line
- 通过扩展反斜杠转义序列打印行
tr "\r\n" "56"
- 暂时将\r\n
替换为56
tr -d "[:cntrl:]"
- 删除所有控制字符
tr "56" "\r\n"
- 恢复新行结尾
那么跟踪某些命令(例如 php
)的完整示例可能如下所示:
strace -e trace=read,write,recvfrom,sendto -s 1000 -fp $(pgrep -n php) 2>&1 | format-strace
检查类似示例:How to view the output of a running process in another bash session? 在 Unix.SE
我跟踪了 strace
命令生成的日志,例如在 运行 PHP 上由:
sudo strace -e sendto -fp $(pgrep -n php) -o strace.log
输出如下:
11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240\r\n72\v[=40=]?[=40=][=40=][=40=]stdClasscidschemadata\n7blockfields\fbidtype 0erialnot nullmodulevarcharlength@\tdefault\rdelta@<em>\v\f \r[=40=]10t 7<code>C
@6\r\r ntatus@0int/[=15=]size 2\finyweight ;[=15=]0 region@80Pcustom
0,\nvisibility0\tpages 5tex@6 1it 5[=40=]0[=16=]7
y\r\ftransl!Nble %ca!a0Q[=40=]n\vprimary key[=17=]\vunique@\tstmd [=17=] 2\v\nindex 0list0[=17=] \n name [=17=]\na7_ro
2[=40=]!$[=40=]\n 1[=40=]0[=40=]A4r!4@ \vunsigned@2[=40=]3[=18=]\n 3[=18=] l%!%
1[=40=]%@p#$\f0l1b@nM&@Ebod1_\tB\g info .[=19=]a5[=19=]0@q!Lforma12B/!d y[=19=]*
y[=40=] 5a;01'\van[=40=]_7
00[=40=]U =@U@2 2lob@O\n)expire@2[=40=]create1< [=21=]\n3\"7[=21=]d
Y[=40=] 5small0!a[=40=].0[=22=].00[=22=]00,\vb Skpo\"3s!0\t1q[=22=] ?\tno 3ort\fm\";ine_A3
21#0!50[=40=]U30[=23=]'ACsourc220[=23=]\v0[=23=]_C60[=23=]74
_030\r[=40=]\vmultipliers[=24=]- 3\t1[=24=]B-[=24=]![=24=]03a3[=24=]05
\v[=40=]05ac 7Dz\"4 [=40=] [=40=] @3\r6563\nidenti$x\nr66\vadmin_celabel\f4H hook0\r[=40=]_05\fsapiown F[=40=]62CB Himum_v 0$curr m0!2[=40=]02\"5[=40=]220N_groupa7632[=25=] 264 5C%1[=25=]P1062aQA:11 c\"$back#0b[=25=]_0!01
C0[=40=]a!2\no 0#0!&}17[=26=][=26=]2e1n;< =0m[=26=]
0[=40=] 2XAz\v>G?@A1\tT103[=40=] B0 string#otoolsbDC 0[=40=]D!DCLE!P[=40=]F 1TGckeditor_set%6[=40=]gE3[=40=]%Q[=40=]# 4@5!)\"w#20[=40=]![=40=] [=40=]04#\n0D \rO0\r_input_4+0V+ 0h X[=40=]!;[=40=]# 5[=40=]+ 7[=40=]Q TRcomme#/[=40=]_%6cko Wpane ;@\v[=40=]_3711F !0F3[=40=]21\"1'B[=40=]e@3A4&f`6\"~\vcollap&q%70[=40=]\t04a09[=40=][=40=]#20.[=40=]010L$7enFl4[=40=]60,[=40=]Gview0[=40=]0207 2[=40=] K[=40=]T!"..., 8196, MSG_NOSIGNAL|MSG_MORE, NULL, 0) = 8196
听起来这些都是普通的C escape codes。
我试图通过 printf
在 shell 中解码它们,例如:
while read line; do printf "%s" "$line"; done < <(cat strace.log | head -n2)
但是失败了(貌似没有任何意义):
11208 sendto(4, "set 29170397297_-cache-schema 85 0 127240rn257202v0?00022710stdClass247213cid216schema214d37ata25n247215block246216fields24f213bid2425214type 037erial2110not null5216module244167217va37rchar216length6@16t5217defaultr215de2lta@<em>516v16f6 35716r210010215t 207<code>C
30@6216rr n4tatus@04213int/760214size 222finy216weight243 ;022300 66region@83405P5custom
27300,171623162421nvisibility340t3475pages242 20534tex@206 2611it 365052400377
y10r21ftransl!N2ble %1ca!a3403Q01n31vprimary key2416016621vunique@21ts241213tmd243 31020 2vn621616217index 210101214list24524036021 3610266316256416n 164214name 70na3172_ro
25205![=41=]n 3341223016340016A2142213r!354@ v222110unsigned5@3320362130n 213016 l6%16!24116%
2710%@p516#16f200l241b@n24166M21016&@E4214bod201_53216t41623Bg1634 303info .07a2550200@q!L56forma201332B/!d241637 y0*
y0 225a;2402012'21van0_207
200251613400U =@U1163@222 2122lob@On2316)216expire@303420267217create24117< 250n2031"1770d
Y022 30555small240!a320.`2300.240240012402403,21vb S2kpo"3132s246!2202t212241q010...
是否有更好的方法来解析 strace
命令的输出以查看传递给 recvfrom
/sendto
的纯字符串?
理想情况下,可以打印包括换行符在内的可打印字符 (\r\n
),但会截断 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" "56" | tr -d "[:cntrl:]" | tr "56" "\r\n"'
其中:
grep -o '".\+[^"]"'
- select 带引号的双引号字符串grep -o '[^"]*[^"]'
- select 双引号内的文字while read -r line
- 将每一行存储到$line
和do
一些动作中 (help read
)printf "%b" $line
- 通过扩展反斜杠转义序列打印行tr "\r\n" "56"
- 暂时将\r\n
替换为56
tr -d "[:cntrl:]"
- 删除所有控制字符tr "56" "\r\n"
- 恢复新行结尾
那么跟踪某些命令(例如 php
)的完整示例可能如下所示:
strace -e trace=read,write,recvfrom,sendto -s 1000 -fp $(pgrep -n php) 2>&1 | format-strace
检查类似示例:How to view the output of a running process in another bash session? 在 Unix.SE