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实际上工作正常......所以你做得对。

我的预感是问题出在“附加”中,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...包括最终将其写入磁盘的那一个...)

另一件可以帮助的事情是在你的链中插入一个“输出到屏幕”窥视器,这显然是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

顺序很重要,不能反过来。

相关内容