如何取消转义 输出的字符串strace
?我看到了一些建议printf '%b'
,但在某些情况下,这些建议对我来说不起作用。请考虑echo -ne '\037\061'
:
$ strace -e write echo -ne '\037\061'
write(1, "\0371", 21) = 2
+++ exited with 0 +++
现在,如果我将其输入到printf
:
$ printf "%b" "\0371" | xxd -p
f9
但实际上却是:
$ echo -ne '\037\061' | xxd -p
1f31
显然,printf %b
解释\0371
为\371
(根据男人)。这种方法printf
不太适合解码strace
输出。我应该用什么来代替呢?
答案1
tl;dr – 请参阅最后的“结论”。
这里发生的事情非常有趣。
首先,echo -e
像这样的行为(来自man 1 echo
):
\0NNN
具有八进制值的字节NNN
(1 至 3 位数字)
这意味着0
in\037
不是八进制数字,它只是\0
表示连续八进制输入的前缀的一部分。您的\037
可能是\0037
,现在只有第二个0
是八进制数字。
仍然在 内echo -e
\061
相当于\0061
。这相当于1
,一个表示“一”的文字字符。
strace
现在看来,您想要解码的输出部分应该按以下方式解码:
write(1, "\0371", 21)
^ prefix that indicates consecutive octal output
^^^ three digits of octal output
^ literal character meaning "one"
所以这里的前缀不是\0
但是\
。
您可以使用printf "%b" "\0371"
。一般形式是printf FORMAT [ARGUMENT]…
,这就是man 1 printf
说关于FORMAT
存在%b
:
%b
ARGUMENT
作为一个带有\
转义符的字符串,但八进制转义符的形式为\0
或\0NNN
如您所见,前缀是\0
,例如echo -e
。现在的解释如下:
printf "%b" "\0371"
^^ prefix that indicates consecutive octal input
^^^ three octal digits
这解释了您的错误结果。然而,同一手册指出,FORMAT
八进制数字的解释方式略有不同:
\NNN
具有八进制值的字节NNN
(1 至 3 位数字)
前缀\
与 的输出完全相同strace
。此外,strace
似乎还要注意下一个字符是否可解释为八进制数字。比较:
$ strace -e write echo -ne '\037'
write(1, "\37", 1) = 1
+++ exited with 0 +++
到
$ strace -e write echo -ne '\037\101'
write(1, "\37A", 21) = 2
+++ exited with 0 +++
到
$ strace -e write echo -ne '\037\061'
write(1, "\0371", 21) = 2
+++ exited with 0 +++
注意最后一种情况下的前导0
。这样做是为了避免\371
被解释为单个字节。
看起来您可以用来printf
解码strace
输出,但您应该将其作为 传递FORMAT
,而不是ARGUMENT
:
$ printf "\0371" | xxd -p
1f31
但是之后在 中解释的其他序列FORMAT
(例如%b
)会给您带来麻烦,因此最好坚持ARGUMENT
。我尝试在适当的情况下将 变成 ,它很快就变得麻烦了;然后我意识到sed
也会\
解释中的其他序列!在我看来这是一条死路。\0
%b
FORMAT
ARGUMENT
结论:改变的行为更好strace
。尝试十六进制输出:
$ strace -xx -e write echo -ne '\037\061'
write(1, "\x1f\x31", 21) = 2
+++ exited with 0 +++
然后
$ printf "%b" "\x1f\x31" | xxd -p
1f31