프로그램이 어떤 파일에 쓰는지 결정하기 위해 다음 코드를 작성했습니다. 물론 파일 이름을 캡처하고 싶습니다.
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... 결국 디스크에 쓰는 것을 포함하여...)
도움이 될 수 있는 또 다른 방법은 체인에 "화면으로 출력"을 삽입하는 것입니다. 이는 분명히 다음과 같습니다 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
순서가 중요하며 되돌릴 수 없습니다.