linux - [Solved-5 Solutions] How to write stderr to a file while using “tee” with a pipe ? - ubuntu - red hat - debian - linux server - linux pc
Linux - Problem :
How to write stderr to a file while using “tee” with a pipe ?
Linux - Solution 1:
Process substitution and file redirection:
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
click below button to copy the code. By - Linux tutorial - team
Let's split it up and explain:
> >(..)
click below button to copy the code. By - Linux tutorial - team
>(...) (process substitution) creates a FIFO and lets tee listen on it. Then, it uses > (file redirection) to redirect the STDOUT of command to the FIFO that your first tee is listening on.
Same thing for the second:
2> >(tee -a stderr.log >&2)
click below button to copy the code. By - Linux tutorial - team
We use process substitution again to make a tee process that reads from STDIN and dumps it into stderr.log. tee outputs its input back on STDOUT, but since its input is our STDERR, we want to redirect tee's STDOUT to our STDERR again. Then we use file redirection to redirect command's STDERR to the FIFO's input (tee's STDIN).
In sh, you'd have to do things manually:
out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"
click below button to copy the code. By - Linux tutorial - team
Linux - Solution 2:
./aaa.sh 2>&1 | tee -a log
click below button to copy the code. By - Linux tutorial - team
This simply redirects stderr to stdout, so tee echoes both to log and to screen.
Note: Since bash version 4 you may use |& as an abbreviation for 2>&1 |:
./aaa.sh |& tee -a log
click below button to copy the code. By - Linux tutorial - team
For Example:
#!/bin/bash
STATUSFILE=x.out
LOGFILE=x.log
### All output to screen
### Do nothing, this is the default
### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1
### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1
### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)
### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)
### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}
### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)
### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}
### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)
echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}
click below button to copy the code. By - Linux tutorial - team
Linux - Solution 4:
To redirect stderr to a file, display stdout to screen, and also save stdout to a file:
./aaa.sh 2>ccc.out | tee ./bbb.out
click below button to copy the code. By - Linux tutorial - team
To display both stderr and stdout to screen and also save both to a file, you can use bash's I/O redirection:
#!/bin/bash
# Create a new file descriptor 4, pointed at the file
# which will receive stderr.
exec 4<>ccc.out
# Also print the contents of this file to screen.
tail -f ccc.out &
# Run the command; tee stdout as normal, and send stderr
# to our file descriptor 4.
./aaa.sh 2>&4 | tee bbb.out
# Clean up: Close file descriptor 4 and kill tail -f.
exec 4>&-
kill %1
click below button to copy the code. By - Linux tutorial - team
Linux - Solution 5:
If using bash:
# Redirect standard out and standard error separately
% cmd >stdout-redirect 2>stderr-redirect
# Redirect standard error and out together
% cmd >stdout-redirect 2>&1
# Merge standard error with standard out and pipe
% cmd 2>&1 |cmd2