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?
the shortcut is Ctrl + Shift + S ; it allows the output to be saved as a text file, or as HTML including colors!
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.
“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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With