Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing outputs to log file and console

In Unix shell, I have a env file (env file defines the parameters required for running the user script like log file name and path, redirect outputs and errors to log file, database connection details, etc) which redirects all the outputs (echo messages) and errors to the log file from the executed script using the following code:

exec 1>>${LOG_FILE} exec 2>>${LOG_FILE} 

The env file is executed at the beginning of each script. Due to the above code in env file all the console outputs that might be user outputs or errors are directly output to the log file which is what I actually needed.

But there are some selective user outputs which I want to be displayed in both the console and the log file. But because of the above code I am not able to do so.

I know that if I remove the above code I can get the desired result for this case, but I will have to manually write all other outputs to the log file which is not an easy task.

Is there a way to get the output in both the console and the log file without removing the above codes?

like image 898
abinash shrestha Avatar asked Aug 27 '13 08:08

abinash shrestha


People also ask

How do you write output to a file?

the shortcut is Ctrl + Shift + S ; it allows the output to be saved as a text file, or as HTML including colors!

How do you output logs into a file in Linux?

Method 1: Use redirection to save command output to file in Linux. You can use redirection in Linux for this purpose. With redirection operator, instead of showing the output on the screen, it goes to the provided file. The > redirects the command output to a file replacing any existing content on the file.

How do I redirect output to a file and screen in Linux?

“tee” command is one of the most valuable tools that helps a Linux user redirect the output of a command to a file and screen. This article discussed the primary usage of “tee” for redirecting output to screen, single, or multiple files.


2 Answers

exec 3>&1 1>>${LOG_FILE} 2>&1 

would send stdout and stderr output into the log file, but would also leave you with fd 3 connected to the console, so you can do

echo "Some console message" 1>&3 

to write a message just to the console, or

echo "Some console and log file message" | tee /dev/fd/3 

to write a message to both the console and the log file - tee sends its output to both its own fd 1 (which here is the LOG_FILE) and the file you told it to write to (which here is fd 3, i.e. the console).

Example:

exec 3>&1 1>>${LOG_FILE} 2>&1  echo "This is stdout" echo "This is stderr" 1>&2 echo "This is the console (fd 3)" 1>&3 echo "This is both the log and the console" | tee /dev/fd/3 

would print

This is the console (fd 3) This is both the log and the console 

on the console and put

This is stdout This is stderr This is both the log and the console 

into the log file.

like image 143
Ian Roberts Avatar answered Sep 21 '22 08:09

Ian Roberts


I tried joonty's answer, but I also got the

exec: 1: not found

error. This is what works best for me (confirmed to work in zsh also):

#!/bin/bash LOG_FILE=/tmp/both.log exec > >(tee ${LOG_FILE}) 2>&1 echo "this is stdout" chmmm 77 /makeError 

The file /tmp/both.log afterwards contains

this is stdout chmmm command not found  

The /tmp/both.log is appended unless you remove the -a from tee.

Hint: >(...) is a process substitution. It lets the exec to the tee command as if it were a file.

like image 20
alfonx Avatar answered Sep 22 '22 08:09

alfonx