Capture output without redirection and leave it on terminal too

io-redirection

I need to capture output of a daemon that also includes a on-demand mode and behaves differently depending on if output goes to tty or not. Just redirecting stdout anywhere makes it go into logging mode where it writes data in inconvenient format and ATM it would take too much time to reconfigure it to do otherwise/fix it/ask author.

Can I somehow just run it as usual – i.e. without redirection – but still get a copy of everything it writes to screen in a file?

Best Answer

You can use socat to make mydaemon's stdout a pseudo terminal device and have all the data written there sent to a pipe by socat.

Here using ls -l /proc/self/fd in place of mydaemon

$ socat  -u 'exec:"ls -l /proc/self/fd",pty,raw' - | tee file.out
total 0
lrwx------ 1 stephane stephane 64 Aug 20 13:32 0 -> /dev/pts/25
lrwx------ 1 stephane stephane 64 Aug 20 13:32 1 -> /dev/pts/26
lrwx------ 1 stephane stephane 64 Aug 20 13:32 2 -> /dev/pts/25
lr-x------ 1 stephane stephane 64 Aug 20 13:32 3 -> /proc/30930/fd

See how ls's stdout is a new pty device (/dev/pts/26)

If you don't have socat, you could also use script:

$ script -qc 'stty raw; ls -l /proc/self/fd' file.out < /dev/null
total 0
lrwx------ 1 stephane stephane 64 Aug 20 13:35 0 -> /dev/pts/26
lrwx------ 1 stephane stephane 64 Aug 20 13:35 1 -> /dev/pts/26
lrwx------ 1 stephane stephane 64 Aug 20 13:35 2 -> /dev/pts/26
lr-x------ 1 stephane stephane 64 Aug 20 13:35 3 -> /proc/31010/fd

(the < /dev/null is so that script doesn't set your terminal in raw mode).

Note however that in that case, all of stdin, stdout and stderr are redirected to that pty. For stdin and stderr to be untouched as with the socat approach, you could do:

$ script -qc 'stty raw; exec <&3 2>&4 3<&- 4>&-; ls -l /proc/self/fd' file.out 3<&0 4>&2 < /dev/null
total 0
lrwx------ 1 stephane stephane 64 Aug 20 13:37 0 -> /dev/pts/25
lrwx------ 1 stephane stephane 64 Aug 20 13:37 1 -> /dev/pts/26
lrwx------ 1 stephane stephane 64 Aug 20 13:37 2 -> /dev/pts/25
lr-x------ 1 stephane stephane 64 Aug 20 13:37 3 -> /proc/31065/fd

Not all script implementations/versions support the -c or -q option.

Note that some systems come with an unbuffer expect script for that but beware it has several bugs and limitations.

Related Question