views:

2782

answers:

3

Hey Everyone,

This one's been bugging me for a while now. Is it possible to redirect stdout and stderr to both the terminal output and to a program?

I understand it's possible to redirect the outputs to a file and to stdout with tee, but I want it to go to a program (my editor [TextMate]) as well as to the terminal output… surely this is possible (I know its possible with zsh…)

Thanks =)

+7  A: 

Is it possible to redirect stdout and stderr to both the terminal output and to a program?

I'm not sure how useful it is to combine stdout and stderr on the input to an editor, but does omething like this do what you need?

input_prog 2>&1 | tee /dev/tty | my_editor
Charles Bailey
Charles, is that "tee >/dev/tty" correct? I've never seen it done that way. I would usually just "tee /dev/tty" to get the effect you're after.
paxdiablo
@Pax @Charles Bailey fixed typo. Rollback if tee> was intended
phihag
Doh, yes, sorry. Obviously stdout can't be redirected and piped at the same time. Thanks.
Charles Bailey
At least on Linux, you can also tee to `/dev/stdout` and `/dev/stderr`
jhs
A: 

I don't actually know whether TextMate can take a file to edit as its standard input, that seems a little bizarre. I suspect you would want to send the stdout/stderr to a file and edit it there, in which case you need:

progname 2>&1 | tee tempfile ; textmate tempfile

The 2>&1 redirects stderr (file handle 2) to go to the same place as stdout (file handle 1) so that both of them end up in a single stream. The tee command then writes that to tempfile as well as stdout.

Then, once the process has finished, the editor is called up on the temporary file.

If it can accept standard input for editing, use:

progname 2>&1 | tee /dev/tty | textmate
paxdiablo
Pipe anything to mate and it'll open in a new document
obeattie
+8  A: 

You can use a named pipe, which is intended for exactly the situation you describe.

mkfifo some_pipe
command_that_writes_to_stdout | tee some_pipe \
  & command_that_reads_from_stdin < some_pipe
rm some_pipe

Or, in Bash:

command_that_writes_to_stdout | tee >(command_that_reads_from_stdin)
jhs
Bash's process substitution will do this for you in one step (sort of an "anonymous named pipe") command_that_writes_to_stdout | tee >(command_that_reads_from_stdin)
oylenshpeegul
@ephemient, thanks!
jhs