如何正确地取消转义 strace 输出

如何正确地取消转义 strace 输出

如何取消转义 输出的字符串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 位数字)

这意味着0in\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%bFORMATARGUMENT


结论:改变的行为更好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

相关内容