27

My aim is to log all output from a script into a directory that the script is going to create.

For example, I have:

~/.abc.sh:

#! /bin/bash
rails new myapp

When I run...

cd ~/code
. ~/.abc.sh

...that will create a new Rails app in directory ~/code/myapp.

When Rails is creating an app, it outputs a whole lot of text that I want to capture and store in a log file in the same directory the rails command newly created. I also want to display that text in the terminal as well.

How do I go about doing this?

Zabba
  • 3,695

2 Answers2

49

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.

Lekensteyn
  • 178,864
  • Do you mean ~/.abc.sh | tee <file> ? If so, then the trouble is I don't know in which directory the script is going to create the app when I call it, so how would I know what to give the in the file argument? (Thanks for the great examples) – Zabba Apr 29 '11 at 18:19
  • @Zabba: what about creating a temporary file and move it afterwards? – Lekensteyn Apr 29 '11 at 18:20
  • Ok, that should work :). In regard to that, how do I create a temp file with a random name that I can then output to and then copy to a desired location afterwards? Is there some built-in command to get a "temp file name" ? – Zabba Apr 29 '11 at 18:21
  • @Zabba: the command for that is mktemp. See the manual page man mktemp. – Lekensteyn Apr 29 '11 at 19:15
  • 跪拜, work like a charm – Sun Junwen Jun 08 '15 at 08:07
  • Does not work perfectly... it seems output is written only at certain times (may be after new line).... – nirala Feb 03 '21 at 18:29
  • To copy both stderr and stdout to a file while having output in the terminal you can also use: command |& tee <file>. – thayne May 10 '23 at 22:54
3

The script command will start an interactive session and log all the output (including stderr) to a file. If you use the -c parameter, it will run a given command, and log the output of that.

script  -c ~/.abc.sh  abc.log

Note: in an interactive session, you can stop recording just by exiting the session as you normally would (e.g. exit or Ctrl-D).

For session recording with video playback, you can also try asciinema.

mwfearnley
  • 3,527
  • 2
  • 24
  • 31