tl; dr - ver "conclusão" no final.
O que acontece aqui é bastante interessante.
Primeiro, echo -e
age assim (de man 1 echo
):
NNN
%b
ARGUMENT
as a string with\
escapes interpreted, except that octal escapes are of the formor
\NNN
byte with octal valueNNN
(1 to 3 digits)%bl0ck_qu0te%NNN
byte with octal valueNNN
(1 to 3 digits)
Isso significa que 0
em 7
não é um dígito octal, é apenas uma parte do prefixo
que indica entrada octal consecutiva. Seu 7
pode ser 0
37echo -e
e agora apenas o segundo 1
é um dígito octal.
Ainda dentro de 1
61strace
é equivalente a
. Isso é equivalente a \
printf "%b" "71"
, um caractere literal que significa "um".
Agora, parece que a parte da saída printf FORMAT [ARGUMENT]…
que você deseja decodificar deve ser decodificada dessa maneira:
write(1, "71", 21)
^ prefix that indicates consecutive octal output
^^^ three digits of octal output
^ literal character meaning "one"
Portanto, o prefixo aqui não é man 1 printf
, mas FORMAT
.
Você usa %b
. A forma geral é
e é isso que echo -e
FORMAT
diz sobre \
sendo strace
:
Como você pode ver, o prefixo é strace
, como em 0
. A interpretação agora é assim:
printf "%b" "71"
^^ prefix that indicates consecutive octal input
^^^ three octal digits
Isso explica o seu resultado errado. No entanto, o mesmo manual declara que dentro de 1
octal digits são interpretados de uma maneira ligeiramente diferente:
O prefixo é printf
exatamente como na saída de strace
. Além disso, FORMAT
parece tomar cuidado sempre que o próximo caractere puder ser interpretado como um dígito octal. Comparar:
$ strace -e write echo -ne '7'
write(1, "", 1) = 1
+++ exited with 0 +++
para
$ strace -e write echo -ne '71'
write(1, "A", 21) = 2
+++ exited with 0 +++
para
$ strace -e write echo -ne '71'
write(1, "71", 21) = 2
+++ exited with 0 +++
Observe o ARGUMENT
no último caso. Está lá para evitar FORMAT
, que seria interpretado como um único byte.
Parece que você pode usar %b
para decodificar ARGUMENT
output, mas deve passá-lo como sed
, não \
:
$ printf "71" | xxd -p
1f31
Mas, em seguida, outras sequências interpretadas dentro de
(por exemplo, %b
FORMAT
) podem causar problemas, por isso é melhor manter o ARGUMENT
. Eu joguei com strace
para transformar %code% em %code% em casos apropriados, ficou incômodo rapidamente; então eu percebi que %code% as %code% também interpretaria outras seqüências em %code% ! Na minha opinião, é um beco sem saída.
Conclusão: é melhor alterar o comportamento de %code% . Tente saída hexadecimal:
$ strace -xx -e write echo -ne '71'
write(1, "\x1f\x31", 21) = 2
+++ exited with 0 +++
Então
$ printf "%b" "\x1f\x31" | xxd -p
1f31