3

Is there a way to use strace to just show a process's stdout? I know I can do

strace -p pid -e write

but that shows calls to write(2) to multiple file descriptors. When reading the man page I also saw the -e write= option but I'm getting a bunch of other stuff when using

strace -p pid -e write=1

Basically, I want the output of the first command (strace -p pid -e write) but only showing the write(1,... outputs. I know I could filter the output, but I'm wondering if there's a way for strace to do this directly.

1
  • 1
    No that's not possible afaik. You'll have to pass the output to grep. See also this Q. It would be great if a more tcpdump-like tool for monitoring system calls existed, but I don't know anything of the sort. Commented Feb 1, 2020 at 22:14

4 Answers 4

4

If you know the PID you can hook the -P parameter to the STDOUT file descriptor in /proc. Just like this:

strace -p PID -P /proc/PID/fd/1 -e write

You can find all open file descriptors of a process in /proc/PID/fd. 1 is a symlink to the STDOUT file.

1
  • Quick tip: use -s <number> to increase the output size. By default, strace will only print 32 chars from the captured line Commented Mar 15, 2023 at 3:36
2

You can filter strace output using the -P parameter, when you know the file descriptor path.

As per documentation:

-y Print paths associated with file descriptor arguments.

-P path Trace only system calls accessing path. Multiple -P options can be used to specify several paths.

It is not necessary to use -y when you use -P. You can use -y to initially find out the path of your file descriptor. This could be something like /dev/pts/0.

Here is an example that can be used to display output from a process that was disconnected from bash using the disown command:

strace -e trace=write -s 1000 -p12345 -P "/dev/pts/0 (deleted)" 2>&1 | awk -F "\"" '{print $2}'

In this example, 12345 is the PID of the process that was started in a bash session and initially wrote to stdout. We disconnected the process from bash using disown 12345 and closed bash. Using the above command, we can display output from this process in a different bash session.

1

No. But perhaps rather than using strace you can simply monitor the pid's stdout using tail -f /proc/<pid>/fd/1 to nevertheless achieve your goal.

Example:

$ for F in $(seq 1 100);do echo $F;sleep 1;done >/tmp/foo 2>&1 &
[1] 163
$ tail -f /proc/163/fd/1
4
5
6
7
8
9
^C
$
2
  • I can run your example, but I'm having trouble getting this to work for the actual process I care about. Seems to open fine but no output, even though strace shows the right output. I'm the owning user so permissions shouldn't be the problem. I inspected the file and it's telling me its an invalid symlink. Any thoughts on what might be wrong here? Commented Feb 1, 2020 at 23:32
  • 2
    This assumes that the standard output is a regular file, which is not a restriction given in the question. Commented Feb 2, 2020 at 10:59
0

I wrote a tool, catp, to do this task. So you can catp $PID.

Basically, it's the same as strace, utilizing ptrace under the hood. Instead of printing various tracing information, it prints the tracee's output to stdout.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.