Как правильно убрать вывод строки

365
torvin

Как я могу удалить строки, выведенные 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
Kamil Maciorowski

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в надлежащих случаях, это стало обременительным быстро; тогда я понял, %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 
Спасибо за подробное объяснение. Мне не нравится идея использования `-x`: это затрудняет чтение выходных данных (теперь мне нужно все декодировать!). `strace -xe write echo -ne '\ 037z'` приводит к `" \ x1f \ x7a "` вместо гораздо более полезного `" \ x1fz "`, что усложняет поиск нужного мне syscal в выводе "strace" torvin 6 лет назад 0

Похожие вопросы