56

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
  • 2
    May be the answer looks the same, but it was not the same question.
    – 4m1nh4j1
    Commented 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
    Commented Jul 21, 2014 at 12:44

2 Answers 2

108

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
    Commented 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
    Commented Mar 29, 2016 at 9:55
  • 1
    On Mac this just simply hangs forever!
    – Prav
    Commented Jan 2, 2021 at 16:30
  • @PraveenPremaratne that may be something to ask another question about, but in general, no, it doesn't. Commented Jan 3, 2021 at 0:59
  • 1
    @xref This question is specifically about Bash, but the accepted answer in the duplicate question ought to work under POSIX sh at the cost of wrapping the body in braces, with more or less the same execution. Commented Nov 5, 2022 at 2:32
8
exec >> $log_file 2>&1 && tail $log_file
1
  • 1
    maybe tail -f?
    – MarSoft
    Commented Aug 14, 2023 at 21:26

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