1

Как мне удалить строки, выведенные с помощью 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 ответ1

2

tl; dr - см. "заключение" в самом конце.


То, что здесь происходит, довольно интересно.

Прежде всего, echo -e действует так (от man 1 echo):

\0NNN
байт с восьмеричным значением NNN (от 1 до 3 цифр)

Это означает, что 0 в \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 как строка с интерпретируемыми \ escapes, за исключением того, что восьмеричные escape-символы имеют форму \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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .