52

In a bash script, how can I redirect all standard outputs to a log file and tee the output on the screen using exec ?

log_file="$HOME/logs/install.txt-`date +'%Y-%m-%d_%H-%M-%S'`"
[ -f "$log_file" ] || touch "$log_file"
exec 1>> $log_file 2>&1

This code redirect all the log to the log file but not to the screen .

2
  • 1
    May be the answer looks the same, but it was not the same question.
    – 4m1nh4j1
    Jul 21, 2014 at 8:28
  • No, it is the exact same question. The first sentence describes what it's trying to do, and it's exactly what you're trying to do: "redirect all output to one file, debug log as well as to the terminal"
    – phemmer
    Jul 21, 2014 at 12:44

2 Answers 2

103

Use process substitution with & redirection and exec:

exec &> >(tee -a "$log_file")
echo "This will be logged to the file and to the screen"

$log_file will contain the output of the script and any subprocesses, and the output will also be printed to the screen.

  • >(...) starts the process ... and returns a file representing its standard input.

  • exec &> ... redirects both standard output and standard error into ... for the remainder of the script (use just exec > ... for stdout only).

  • tee -a appends its standard input to the file, and also prints it to the screen.

8
  • 1
    It works, but sometimes I still get output when I already have my console prompt, resulting in a mixed output.
    – Halfgaar
    Oct 28, 2015 at 9:15
  • 1
    @Halfgaar - That is expected as exec replace the process including file descriptors for STDIN, STDOUT and STDERR - effectively detaching it from the terminal but tee continues to emit anything it receives.
    – shalomb
    Mar 29, 2016 at 9:55
  • 1
    On Mac this just simply hangs forever!
    – Prav
    Jan 2, 2021 at 16:30
  • @PraveenPremaratne that may be something to ask another question about, but in general, no, it doesn't. Jan 3, 2021 at 0:59
  • I thought I had the same result on Linux as Praveen, but it turned out that I was at the command prompt. If I type something, I get command not found. If I add an exit to the script, I get my command prompt back. I'm testing using a script with just a single echo statement.
    – Vince
    May 3, 2021 at 4:18
8
exec >> $log_file 2>&1 && tail $log_file
1
  • maybe tail -f?
    – MarSoft
    Aug 14 at 21:26

Not the answer you're looking for? Browse other questions tagged .