Linux – Redirect stdout while a process is running — What is that process sending to /dev/null

bashlinuxoperating systems

I've run a command and redirected it's output via > /dev/null
Now that it's been running significantly longer than I expected I want to see what it's doing.

Is there a way to re-redirect the output, such that all the new contents would be printed to stdout? I realize that all the previous contents are gone.

Best Answer

You can do it using strace.

Using strace you can spy what is being written to file-descriptor 1, which is the stdout file descriptor. Here is an example:

strace  -p $pid_of_process_you_want_to_see_stdout_of 2>&1 | \
    sed -re 's%^write\(1,[[:blank:]](.*),[[:blank:]]*[0-9]+\)[[:blank:]]*=[[:blank:]]*[0-9]+%\1%g' 

You may want to improve the filter, but that would be another question. We have the output, but now need to tidy it.

:WARNING: This solution has some limitations, see comments below. It will not always work, your mileage may vary.

Test:

Put this program (below) in file hello, and chmod +x hello

#!/bin/bash

while true
do
    echo -en  "hello\nworld\n"
done

This one in hello1 and chmod +x hello1

#!/bin/bash
dir=$(dirname $0)
$dir/hello >/dev/null

This one in hello2 and chmod +x hello2

#!/bin/bash
dir=$(dirname $0)
$dir/hello1 >/dev/null

then run with ./hello2 >/dev/null, then find pid of process hello and type pid_of_process_you_want_to_see_stdout_of=xyz where xyz is the pid of hello, then run line at top.

How it works. When hello is run, bash forks, redirects fd 1 to /dev/null, then execs hello. Hello sends output to fd1 using system call write(1, …. Kernel receives system call write(1, …, sees that fd 1 is connected to /dev/null and …

We then run strace (system-call trace) on hello, and see that it is calling write(1, "hello\nworld\n") The rest if the line above is just selecting the appropriate line of the trace.

Related Question