[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: colored verbose
From: |
Greg Wooledge |
Subject: |
Re: colored verbose |
Date: |
Wed, 8 Nov 2023 07:47:22 -0500 |
On Wed, Nov 08, 2023 at 11:26:36AM +0100, lacsaP Patatetom wrote:
> is it possible to distinguish the lines displayed by bash's verbose mode by
> coloring them ?
First of all, bash's "verbose mode" is usually worthless. It is NOT
the same as trace mode (-x). Usually you want trace mode instead.
However, I'll give you the benefit of the doubt and assume you either
have some compelling need for verbose mode, or that you're clever enough
to replace -v with -x once you realize that's what you really want.
Now, on to the answer:
Not as such. However, we can determine experimentally that "verbose mode"
writes lines to stderr:
unicorn:~$ bash -v foo >/dev/null
#!/bin/bash
echo hello world
true
(It's actually undocumented. Probably because nobody uses verbose mode
or cares about it. Seriously, trace mode is what you want. It even
lets you specify a custom FD, so you can intercept *only* trace mode
output, and not ordinary stderr, if that's useful to you.)
Knowing this, we could set up a filter that intercepts stderr, and adds
colorization around each "line" written there. Doing this will cause
desynchronization of the stdout and stderr streams, so only do it if
this is not a problem for your script.
Also, if you don't arrange for the stderr filter to be terminated and
waited for, you may get the next shell prompt before you get the filtered
stderr lines.
> for example, with this little script, make the first and third displayed
> lines stand out by coloring them :
>
> bash -v <<~~~
> echo hello world
> seq 5
> ~~~
> echo hello world
> hello world
> seq 5
> 1
> 2
> 3
> 4
> 5
Yeah, see, you are NOT going to get the individual lines of the streams
in the correct order if you do this. Maybe that's a problem for you, and
maybe it's not. I dunno.
Anyway, here's a simplistic implementation to play with:
========================================================================
#!/bin/bash
# Set up stderr filtering, and then turn on verbose mode.
filter() {
local red=$(tput setaf 1)
local sgr0=$(tput sgr0)
local line IFS=''
while read -r line; do
printf '%s%s%s\n' "$red" "$line" "$sgr0"
done
}
exec 2> >(filter >&2)
trap 'exec 2>&-; wait' EXIT
set -v
# Actual script:
echo hello world
true
========================================================================
And running it:
========================================================================
unicorn:~$ ./foo
hello world
# Actual script:
echo hello world
true
exec 2>&-; wait
unicorn:~$
========================================================================
Everything from "#" to "wait" is red. Stderr was delayed by the
filtering, as expected.
With a slightly different script it becomes a little less terrible:
========================================================================
unicorn:~$ ./foo
(RED) # Actual script:
(RED) sleep 1
hello world
(RED) echo hello world
(RED) sleep 1
good-bye
(RED) echo good-bye
(RED) exec 2>&-; wait
unicorn:~$
========================================================================
I added (RED) in front of each colorized line in this example. When
the commands take longer to run, the desynchronization becomes less
of an issue. Slightly. Here's an even better demonstration:
========================================================================
unicorn:~$ ./foo
(RED) # Actual script:
(RED) sleep 1; echo hello world
hello world
(RED) sleep 1; echo good-bye
good-bye
(RED) exec 2>&-; wait
unicorn:~$
========================================================================
If *every* line full of commands has a significant delay before it
writes output, then you won't even notice the desynchronization. Anyway,
that's what we've got. Have fun.
Re: colored verbose, alex xmb sw ratchev, 2023/11/08