mycommand 2>&1 | tee mylog.log
But, as explained before, I need more than that.
b) Color stderr red on a console
Again, not a big issue:
exec 3>&1 mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of command exec 3>&- #housekeeping, close file handle 3
Basically, every stdout line is being injected with ansi codes to turn them red. Of course, an ansi-compatible console is required - I'm using cmder/ConEmu for Windows.
Anyway, the output is exactly what I need. In fact, this is what I meant with " stdout and stderr being displayed in the order they are being produced":
c) Joining all together
This should also be straightforward with something like:
myfunc() { exec 3>&1 set -o pipefail mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of $EXEC_COMMAND exec 3>&- #housekeeping, close file handle 3 echo exit_code: $EXIT_CODE } myfunc | tee mylog.log echo "EXIT_CODE: $EXIT_CODE"
But it is not straightforward. At least not for me, namely because now mycommand's stderr is only being displayed after I exit my app (which was executed running "mycommand"):
Also, as a side effect, I cannot manage to get the EXIT_CODE value outside the function.
I saw similar issues on this, but all seemed to be related with while loops running in a subshell, "redirection" and\or "process substitution". I still wasn't able to solve my specific issue.
So, my questions are:
namely because now mycommand's stderr is only being displayed after I exit my app
How to have stdout and stderr to both console and file, having red stderr lines and "stdout and stderr being displayed as they are being produced" (See Fig.1)?
Both stderr and stdout of your program become block buffered when the output is not a terminal. stdout
is block buffered because mycommand
is not outputting to the terminal and sed
s output is not a terminal and it's outputting stderr, so stderr becomes also block buffered. Configure your program to configure it's stdout/stderr to be line buffered, or you could potentially set initial buffering with stdbuf -oL -eL
and use sed -u
or stdbuf -oL sed
.
How to get the EXIT_CODE value outside the function body?
$EXIT_CODE
to a temporary file.or return the exit code from your function and use PIPESTATUS as you did.
myfunc() {
{
stdbuf -oL -eL mycommand 2>&1 >&3 | sed -u $'s,.*,\e[31m&\e[m,'
EXIT_CODE=${PIPESTATUS[0]}
} 3>&1
echo exit_code: $EXIT_CODE
return "$EXIT_CODE"
}
myfunc | tee mylog.log
echo "EXIT_CODE: ${PIPESTATUS[0]}"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.