[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] How to merge stdout and stderr yet distinguish what is f
From: |
João Eiras |
Subject: |
Re: [Help-bash] How to merge stdout and stderr yet distinguish what is from stdout and what is from stderr? |
Date: |
Sun, 4 Feb 2018 23:24:04 +0100 |
Hi !
You have two options
1) easy solution, prepend something to the lines coming from each file
descriptor
( command 1> >(awk '{print "1" $0}') 2> >(awk '{print "2" $0}') ) >
all_my_output.txt
Note: both sub-shells running awk will output to stdout, so both
outputs are merged
2) fancy solution, keep both stdout and stderr separate and handle
them independently.
This code is more complicated, but it conveniently wrapped with a function
function run_command_with_output_handler {
local output_handler="$1"
shift
local p1=/tmp/stdout.pipe.$BASHPID p2=/tmp/stderr.pipe.$BASHPID
"$@" 1>"$p1" 2>"$p2" &
(while [[ 1 ]] ; do
line=
pipe_broken=0
timed_out=0
for fd in 101 102; do
read -r -t 0.005 -u $fd line
readstatus=$?
[[ $readstatus -gt 127 && ${#line} = 0 ]] && timed_out=$(($timed_out + 1))
[[ $readstatus = 0 || ${#line} != 0 ]] && break
[[ $readstatus = 1 ]] && pipe_broken=$(($pipe_broken + 1))
done
# Both pipes are closed, so the task ended
[[ $pipe_broken -ge 2 ]] && break
# Both pipes timed out so so the task has not written anything meanwhile.
# Find way to use
http://man7.org/linux/man-pages/man2/select.2.html instead of a sleep.
[[ "$timed_out" = 2 ]] && { sleep 0.05 ; continue ; }
# Now fd is either 101 or 102 and $line is not empty, use at will.
output_handler "${fd:2}" "$line"
done) 101<"$p1" 102<"$p2"
wait
rm -f "$p1" "$p2"
}
function my_output_handler {
echo "Fd: $1. line: $2"
}
some_command=( lots of stuff here and arguments )
run_command_with_output_handler my_output_handler "address@hidden"
Note: part of this code was just typed in the e-mail and not tested.
Hope this helps.
Cheers.