2

Say I've started program and it continues writing some output to stdout. Is there some way to add a pipe so that I can, for example, count the number of lines it has produced with wc -l?

cheft
  • 25

2 Answers2

2

You can do this in Linux. Say there's a script s:

#!/bin/bash
i=0
echo my pid: "$$"
while true; do
    echo "$i"; ((i++)); sleep 1; 
done

Run it:

$ ./s
my pid: 8815
0
1
2

And so it goes... Now you need gdb to attach to the process.

gdb -p 8815

Now you're in gdb. Here do this:

p close(1)

This has closed the STDOUT file descriptor. Now open a new one:

p creat("/tmp/8815.out", 0600)

In another terminal you can already set the reading process:

tail -f /tmp/8815.out

Nothing's coming yet, as you need to detach from gdb in the other terminal. Either Ctl+D, or:

q
Quit anyway? (y or n) 

Confirm with y and Enter. And now you should see (where the tail is running) something like this:

173
174
175

If you prefer to use an already existing file or pipe, do this in gdb:

p open("/path/to/your/output", 1)

This illustrates redirecting STDOUT. It's similar with STDERR, only it has number 2.


I used these two answers:

0

You can use tee when you start the program. If you're using bash, you can do:

program > >(tee -a log.txt)

That will redirect the stdout of program to a process substitution running tee. That essentially writes a copy of the stdout of program to log.txt. tee will continue to send the stdout to wherever it was going before, probably the terminal depending on how program works.

m0dular
  • 1,261
  • This is useful but can i do this if I've already started program? – cheft May 25 '18 at 20:33
  • I'm not sure, but it might be possible with strace. Try https://stackoverflow.com/questions/593724/redirect-stderr-stdout-of-a-process-after-its-been-started-using-command-lin – m0dular May 25 '18 at 20:45