プログラムがどのファイルに書き込むかを決定するために、次のコードを書きました。もちろん、ファイル名をキャプチャしたいです。
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
。これは引数なしでは基本的に何もしないようです。| echo
echo
実際、私の箱ではうまくいきます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
順序は重要で、元に戻すことはできません。