help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Hook for `set -v`


From: Peng Yu
Subject: Re: [Help-bash] Hook for `set -v`
Date: Wed, 10 Jun 2015 17:17:37 -0500

On Wed, Jun 10, 2015 at 3:20 PM, Greg Wooledge <address@hidden> wrote:
> On Wed, Jun 10, 2015 at 03:00:29PM -0500, Peng Yu wrote:
>> I want to highlight everything of the original lines printed via set -v.

I want to highlight the lines printed when 'set -v' is enabled.

For exmaple, when `set -v`, the command `echo xxx` will porint both
"echo xxx" and "xxx". I want the output "echo xxx" be highlighted, so
that it is easier to see especially when there are many commands run.
Is it clear?

The foo example that you showed below print the highlight commands all
at once. I want the commands and their output be interleaved as what
happens with `set -v`.

> So, let me get this straight:
>
> You want to run a script.  With set -v in effect.  Which means you get
> the script's output, and set -v's output, intermixed together.
>
> You want to be able to separate them, or identify which line came from
> where.
>
> The manual does not list ANY details about how set -v works.  It literally
> says only, "Print shell input lines as they are read."  No idea whether
> that means print on stdout, print on stderr, etc.
>
> So, let's assume you have NO control over what set -v does.
>
> You DO have control over what the script does.
>
> You could highlight the script's output instead.  Or redirect the script's
> output to a file, etc.  That would give you the ability to see which line
> of output came from where.
>
> I still have no clue why you think set -v's output is useful in any way.
>
>
> So, let's run a little test.  Here's a script:
>
> imadev:~$ cat foo
> #!/bin/bash -v
>
> foo() {
>   echo "$1 bottles of beer on the wall"
> }
> for ((i=5; i; i--)); do
>   foo "$i"
> done
>
> Let's run it:
>
> imadev:~$ ./foo
> #!/bin/bash -v
>
> foo() {
>   echo "$1 bottles of beer on the wall"
> }
> for ((i=5; i; i--)); do
>   foo "$i"
> done
> 5 bottles of beer on the wall
> 4 bottles of beer on the wall
> 3 bottles of beer on the wall
> 2 bottles of beer on the wall
> 1 bottles of beer on the wall
>
> As I said earlier, it reads the function definition, then reads the loop,
> each of which produces a blob of set -v output; then it runs the loop
> without any further set -v output.
>
>
> Now let's see if we can figure out where set -v's output actually went.
> Is it stderr?
>
> imadev:~$ ./foo 2>/dev/null
> 5 bottles of beer on the wall
> 4 bottles of beer on the wall
> 3 bottles of beer on the wall
> 2 bottles of beer on the wall
> 1 bottles of beer on the wall
>
> Yes!  It is stderr.
>
> So, if you want to highlight only the set -v output, you can attach a
> filter to stderr.  (And make sure nothing else writes to stderr.)
>
> For example,
>
> imadev:~$ cat foo
> #!/bin/bash -v
>
> exec 2> >(
>   red=$(tput setaf 1) norm=$(tput sgr0)
>   while read -r; do echo "$red$REPLY$norm"; done >&2
> )
>
> foo() {
>   echo "$1 bottles of beer on the wall"
> }
> for ((i=5; i; i--)); do
>   foo "$i"
> done
>
> sleep 1
>
> And, running it:
>
> imadev:~$ ./foo
> #!/bin/bash -v
>
> exec 2> >(
>   red=$(tput setaf 1) norm=$(tput sgr0)
>   while read -r; do echo "$red$REPLY$norm"; done >&2
> )
>
>   red=$(tput setaf 1) norm=$(tput sgr0)
> tput setaf 1
> 5 bottles of beer on the wall
> 4 bottles of beer on the wall
> 3 bottles of beer on the wall
> 2 bottles of beer on the wall
> 1 bottles of beer on the wall
> tput sgr0
>   while read -r; do echo "$red$REPLY$norm"; done >&2
>
> foo() {
>   echo "$1 bottles of beer on the wall"
> }
> for ((i=5; i; i--)); do
>   foo "$i"
> done
>
> sleep 1
>
>
> There you go.  Now the set -v output (which appears whenever the
> background filter job gets around to writing it) is red.  Useless,
> but red.  Well, other than the initial setup before the filter is
> finished loading.  That part's still unfiltered, because hey, chicken
> and egg.  (You could filter stderr externally to work around that.)
>
> Another approach would be to leave stderr unfiltered, and filter stdout
> instead.
>
> One of these days someone is going to ask a question that actually
> contains a sensible statement of desired outcome, and that actually
> makes sense to do in bash, and I am going to die of shock.



-- 
Regards,
Peng



reply via email to

[Prev in Thread] Current Thread [Next in Thread]