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. 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" 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. 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. Commented Mar 29, 2016 at 9:55
  • 1
    On Mac this just simply hangs forever! 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
  • 2
    maybe tail -f? Commented Aug 14, 2023 at 21:26

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.