I made a simple logger which has method logMETHOD
. It's job is to
stderr
and stdout
to a variable log
(and later to my global _LOG
variable) stderr
of invoked method on stderr
and stdout
on stdout
so I can see it in a console.It's invocation looks like this:
logMETHOD myMethod arg1 arg2 arg3
I figured out how to put standard and error output to both log
variable and a console but I cannot get the right return code.
My code so far:
function logMETHOD {
exec 5>&1
local log
log="$($1 ${@:2} 2>&1 | tee /dev/fd/5)"
local retVal=$?
_LOG+=$log$'\n'
return $retVal
}
Unfortunately the return code I get comes from (probably) assigning a value (or from tee
maybe).
BONUS QUESTION:
Is there a possibility to achieve my goals without 2>&1
which connects stdout
with stderr
also for console?
I tested solution with 'PIPESTATUS' but the code is still 0.
function main {
logMETHOD alwaysError
}
function logMETHOD {
exec 5>&1
local log
local retVal
log="$( "$@" 2>&1 | tee /dev/fd/5 )"
retVal=${PIPESTATUS[0]}
echo "RETVAL: $retVal"
echo "LOG: $log"
_LOG+=$log$'\n'
return $retVal
}
function alwaysError {
return 1
}
main $@
PIPESTATUS
would be a good solution, but here it already holds the return value of the log=...
assignment. If you want the return value of the "$@"...
you have to write it like this:
log="$( "$@" 2>&1 | tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
retVal=$(</tmp/retval)
Assigning it to a variable would not work, because its scope would not extend to the calling shell, so you have to resort to using a tempfile.
As for stderr
, $()
can only extract stdout
, therefore you have to use a tempfile for that too, if you want to handle it separately.
log="$( "$@" 2>/tmp/stderr | tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
stderr_log=$(</tmp/stderr)
retVal=$(</tmp/retval)
If you just want to spare the redirection:
log="$( "$@" |& tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
From man bash
:
If |& is used, command's standard error, in addition to its standard output, is connected to command2's standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error to the standard output is performed after any redirections specified by the command.