Thomas Kostas
Thomas Kostas

Reputation: 455

Redirect stdout and stderr to file permanently but keep printing them

By doing the following(1):

 exec >> log_file
 exec 2>&1
 ls

stdout and stderr is permanently redirected for the next commands but not anymore displayed on terminal. Here, ls output will be in log_file but not displayed in terminal

By doing the following(2):

command | tee log_file

command output will be both in log_file and printed on terminal but this will work only for command and not for the next commands as method 1.

How to redirect permanently stdout and stderr output in a file for a given terminal like method 1 and, keep stdout and stderr printed on the terminal instance like method 2 ?

Upvotes: 4

Views: 4581

Answers (3)

A1 paper
A1 paper

Reputation: 82

Hickory420's answer cannot be used in sh. After searching online for a long time, I finally found a way to use it in sh, bash or any shell.

# Redirect the stdout/stderr to screen AND log file

mkfifo /tmp/$$-err /tmp/$$-out
# to merge stdout/stderr to log file AND screen
( exec tee -a ${FILE_LOG} </tmp/$$-out ) &
( exec tee -a ${FILE_LOG} </tmp/$$-err >&2 ) &

exec 1>/tmp/$$-out
exec 2>/tmp/$$-err
rm -f /tmp/$$-out /tmp/$$-err

refer: Redirect STDOUT & STDERR to file and then on screen

Upvotes: 1

Hickory420
Hickory420

Reputation: 151

I currently use this in my scripts:

exec > >(tee -a "${FILE_Log}" )
exec 2> >(tee -a "${FILE_Log}" >&2)

Basically you are telling bash to send the output (both stdout and stderr) to tee's stdin, and since tee is running in the subshell (within the parentheses), it will live as long as your script does.

Put that somewhere near the top, then any and all command output, echo, print, and, printf will be logged.

This saves having to create a LOG() function and constantly piping commands to tee

Hope that helps!

Upvotes: 6

Chen A.
Chen A.

Reputation: 11328

Using tee and redirection combined:

(exec 2>&1) | tee file.txt

Here's an example

[root@box ~]# (ll 2>&1) | tee tmp.txt
total 4
-rw-------. 1 root root 1007 Apr 26  2017 anaconda-ks.cfg
[root@box ~]# cat tmp.txt
total 4
-rw-------. 1 root root 1007 Apr 26  2017 anaconda-ks.cfg

The reason the command is inside paranthesis is to keep the order of the prints, since stdout is buffered. It causes the ll command to be executed in a subshell, and then return the output of stdout + stderr in-order.

Upvotes: 0

Related Questions