grep strace 出力が難しくなります。

grep strace 出力が難しくなります。

プログラムがどのファイルに書き込むかを決定するために、次のコードを書きました。もちろん、ファイル名をキャプチャしたいです。

strace -f -t -e trace=file -p 8804 2>&1 | grep -oP "\"(.*)\".*O_WRONLY"

この出力は次のようになります。

/tmp/11111111.txt", O_WRONLY

問題は、これらすべての出力をどのコマンドにもパイプできないことです。

strace -f -t -e trace=file -p 8804 2>&1 | grep -oP "\"(.*)\".*O_WRONLY" | echo
# does not show anything

また、後で使用するためにこれらの結果をすべて保存することはできません。

strace -f -t -e trace=file -p 8804 2>&1 | grep -oP "\"(.*)\".*O_WRONLY" > asd.out
# file is empty

ご協力ありがとうございます。 :)

答え1

出力をファイルに書き込んstrace -o asd.outでから ( を使用して) grep できます。

strace マニュアルから:

-o filename Write  the  trace  output to the file filename rather than 
to stderr.  Use filename.pid if -ff is used. If the argument begins with
`|' or with `!' then the rest of the argument is treated as a command
and all output is piped to it. This is convenient for piping the
debugging output to a program without affecting the redirections of 
executed programs.

答え2

今日も同じ問題が発生しました。

FWIWは、あなたの例では、代わりに使用することができます| cat。これは引数なしでは基本的に何もしないようです。| echoecho

実際、私の箱ではうまくいきますstrace ls 2>&1 | grep "execve" > asd.out...それであなたは正しいことをしています。

私の直感は、問題がAppendにあるということです。strace -p xxx通常、終了するにはクリックする必要があり、ctrl+cコマンドチェーンの中間バッファは次のとおりです。フラッシュなし

だからこれは私にとって効果的です(私の考えでは、「スクリーン」/ターミナル/ ttyとして出力されることを検出するので、新しい行からフラッシュされるようです)。

strace ruby -e "sleep" 2>&1 | grep execve

しかし、これはそうではありません

strace ruby -e "sleep" 2>&1 | grep execve > my_output_file

(最終リダイレクトは「ttyではない」ものなので、より大きな4k内部バッファなどを使用したり、「ライン別」バッファリングの代わりに内部バッファを使用するようです。)

しかし、ヒントを活用するとここ、これは動作します:

strace ruby -e "sleep" 2>&1 | stdbuf -oL grep execve > me

非常に奇妙なもの。不安な方法で。私の理論は、より長いチェーンの場合(たとえば、grep | grep | grepバッファのサイズが線形に増加します...一度に4k...最終的にディスクに書き込むことを含む...)

役に立つもう1つの方法は、チェーンに「画面に出力」を挿入することです。これは明らかに次のとおりですtee /dev/tty

strace ruby -e "sleep" 2>&1 | tee /dev/tty | grep execve > my_output_file

出力ファイルに含まれていなくても、少なくとも画面に表示されます。

したがって、とにかくstraceは「通常」として記録されますstderr(たとえば、「プロセス実行中」の場合、strace lsプロセスとstraceの出力は次のようになります)。混合)。このパラメータを使用すると、混合を回避できます-o output_file

また、stdoutを最初にリダイレクトしてからstderrをリダイレクトする必要があります。たとえば、次のようになります。

progname >out.txt 2>&1

順序は重要で、元に戻すことはできません。

関連情報