55

I want to see the output of a command in the terminal as if there was no redirection. Also, stderr needs to be redirected to err.log and stdout needs to be redirected to stdout.log.

It would be nice to also have the exact copy of what is shown in terminal, i.e. errors printed as and when it occurs, in a separate file: stdouterr.log.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
balki
  • 4,407
  • I still find this question very familiar. Let me look up... Here is a very similar one http://unix.stackexchange.com/q/4195/250, and here is a related one http://unix.stackexchange.com/q/1416/250 – phunehehe Jan 25 '11 at 15:57

3 Answers3

64

Use the tee command as follows:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 is how you swap stderr and stdout, because tee can only accept stdout.

Take a look at Unix tee command for more advanced redirections using tee.

dogbane
  • 29,677
  • 1
    nice solution. Is there any way to get cmd exit code? – turbanoff Jun 19 '15 at 16:56
  • 2
    @turbanoff Replace cmd with (cmd ; echo >exit_code.txt $?). – Parthian Shot Aug 13 '15 at 21:04
  • I believe this should better-preserve the order of things output to the command line: ((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) – TTT May 07 '19 at 17:12
  • 1
    This solution fails to address: "I want to see the output of a command in the terminal as if there was no redirection." There is a race condition and thus lines output to terminal will be randomly ordered. – Quasímodo Apr 26 '22 at 00:50
  • ___Unix tee command___ link doesn't work – msciwoj Aug 12 '22 at 08:16
  • Doesn't this leave the output swapped? – nroose Apr 17 '23 at 15:34
  • May I ask why if the parentheses (subshell) are missing, there is nothing going into the stderr? @TTT Why wrapping in the subshell will preserve the order? – midnite Jan 26 '24 at 13:09
  • I see it now! It is because of precedence. Redirection is having a higher precedence than pipes. We may use { ... ;} in-place of ( ... ) which is better not spawning extra sub-shells. – midnite Jan 26 '24 at 20:37
7

I think logging stdout and stderr to two different files is a splendid idea. Does it not make the logs asynchronous? So I tried out the following:

  • stdout to "stdout.log" (as dogbane suggested)
  • stderror to "stderr.log" (as dogbane suggested)
  • all output to "all.log" and
  • still be able to see the output on the display (in a separate terminal though!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

in another terminal

tail -f --sleep-interval=2 all.log
Sreeni
  • 79
  • Is it not possible to direct stderr directly to a second tty? Then no logfile is required. – Steven Lu Apr 25 '13 at 18:40
  • @StevenLu yes, if you know the name and have permission to write to the second tty that can be done. – Jasen Dec 14 '15 at 23:46
  • 1
    easier would be &| tee all.log on the end of the command instead of &> all.log – Jasen Dec 14 '15 at 23:49
  • @Jasen: 2nd time I see &| . I understand &>, |& too, but what does &| mean in this context ? I could not find a suitable syntax reference, not on the net, not even consulting the bash manual page "bash(1)"... Tx – Cbhihe Feb 07 '16 at 16:25
  • 1
    @Cbhihe as far as I can tell it does nothing, I meant to say |& – Jasen Feb 07 '16 at 19:05
  • >& redirects STDOUT and STDERR simultaneously. | pipes STDOUT only, STDERR still goes to the "screen." ' |& pipes STDOUT _and_ STDERR. Thuscmd |& tee fileis shorthand forcmd 2>&1 | tee file` – Scottie H Jul 16 '19 at 15:49
  • 1
    This solution fails to address: "I want to see the output of a command in the terminal as if there was no redirection." There is a race condition and thus lines output to terminal will be randomly ordered. – Quasímodo Apr 26 '22 at 00:50
3

@dogbane, Thanks.
I found another way too which saves both the streams approximately in the order as they would get printed without redirection.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

But this works only with the shells which supports process substitution.

balki
  • 4,407
  • 1
    This solution fails to address: "I want to see the output of a command in the terminal as if there was no redirection." There is a race condition and thus lines output to terminal will be randomly ordered. – Quasímodo Apr 26 '22 at 00:50