33

I have some scripts where I need to see the output and log the result to a file, with the simplest example being:

$ update-client > my.log

I want to be able to see the output of the command while it's running, but also have it logged to the file. I also log stderr, so I would want to be able to log the error stream while seeing it as well.

P Shved
  • 96,026
  • 17
  • 121
  • 165
Kristopher Ives
  • 5,838
  • 7
  • 42
  • 67

4 Answers4

59
update-client 2>&1 | tee my.log

2>&1 redirects standard error to standard output, and tee sends its standard input to standard output and the file.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • 1
    You can also append the log file, as explained here, and do other stuffs with tee: http://linux.101hacks.com/unix/tee-command-examples/ – thegeek Jul 12 '10 at 08:18
7

You can use the tee command for that:

command | tee /path/to/logfile

The equivelent without writing to the shell would be:

command > /path/to/logfile

If you want to append (>>) and show the output in the shell, use the -a option:

command | tee -a /path/to/logfile

Please note that the pipe will catch stdout only, errors to stderr are not processed by the pipe with tee. If you want to log errors (from stderr), use:

command 2>&1 | tee /path/to/logfile

This means: run command and redirect the stderr stream (2) to stdout (1). That will be passed to the pipe with the tee application.

Learn about this at askubuntu site

Anurag Jain
  • 439
  • 5
  • 12
  • Can we tell tee to ignore `clear` and other control charater? Using any of these answer works great except if you do `cat /path/to/logfile` the clear command is reproduced. – Louis Loudog Trottier Nov 07 '19 at 02:25
6

Just use tail to watch the file as it's updated. Background your original process by adding & after your above command After you execute the command above just use

$ tail -f my.log

It will continuously update. (note it won't tell you when the file has finished running so you can output something to the log to tell you it finished. Ctrl-c to exit tail)

Cfreak
  • 19,191
  • 6
  • 49
  • 60
4

another option is to use block based output capture from within the script (not sure if that is the correct technical term).

Example

#!/bin/bash 
{
  echo "I will be sent to screen and file"
  ls ~
} 2>&1 | tee -a /tmp/logfile.log

echo "I will be sent to just terminal"

I like to have more control and flexibility - so I prefer this way.

rynop
  • 50,086
  • 26
  • 101
  • 112