Discussion:
[Help-bash] `set -v` difference in () vs not in ()
Peng Yu
2018-06-09 22:32:23 UTC
Permalink
Hi,

-v Print shell input lines as they are read.

`set -v` behave differently whether it is in () or not. It seems that
is not documented. Why is it defined so?

$ cat ./main.sh
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

(
set -v
echo "Hello World!"
)

set -v
echo "Hello World!"
$ ./main.sh
Hello World!
echo "Hello World!"
Hello World!
--
Regards,
Peng
João Eiras
2018-06-09 23:13:59 UTC
Permalink
Post by Peng Yu
Hi,
-v Print shell input lines as they are read.
`set -v` behave differently whether it is in () or not. It seems that
is not documented. Why is it defined so?
You need to know how bash parses files.

Bash will read one line of input and execute, and move to the next line.
So, in the second example "set -v" is read and executed, and then the
"echo" is executed.

But, when bash finds a code block, started by a bracket or
parenthesis, bash first reads the whole block and then executes.
So, it'll read "(set -v ; echo ...)" and then execute, so "set -v"
will be set AFTER the input is read.
If you set "set -v" at the top of the script, then the "(set -v...)"
block will be output.
Greg Wooledge
2018-06-11 12:27:24 UTC
Permalink
Post by Peng Yu
-v Print shell input lines as they are read.
Which is almost entirely useless. It doesn't help you debug a script.
I don't know why people keep trying to use it.

I could see it maybe possibly helping Chet debug bash. But not a script.
Mike McClain
2018-06-12 03:43:34 UTC
Permalink
Post by Greg Wooledge
Post by Peng Yu
-v Print shell input lines as they are read.
Which is almost entirely useless. It doesn't help you debug a script.
I don't know why people keep trying to use it.
I could see it maybe possibly helping Chet debug bash. But not a script.
Hi Greg,
While I don't doubt for a minute that you know what you're talking
about, I don't.
How is this different than an echo ""? The bash version of the
proverbial 'print statement' used by programmers everywhere?
Thanks,
Mike
--
Today is International Disturbed People's Day
Please send an encouraging message to a disturbed friend.
... Just as I've done.
Greg Wooledge
2018-06-12 12:10:27 UTC
Permalink
Post by Mike McClain
Post by Greg Wooledge
Post by Peng Yu
-v Print shell input lines as they are read.
Which is almost entirely useless. It doesn't help you debug a script.
I don't know why people keep trying to use it.
I could see it maybe possibly helping Chet debug bash. But not a script.
Hi Greg,
While I don't doubt for a minute that you know what you're talking
about, I don't.
How is this different than an echo ""? The bash version of the
proverbial 'print statement' used by programmers everywhere?
Bash (and sh) has two different "debug" options: -x and -v.

set -x tells bash (or sh) to print each command as it is being
*executed*, showing parameter expansions. It is a useful tool.

set -v tells bash (or sh) to print each *line* of the script as it
is being *read*. But this is not useful, because the point at which
a line of input is read has nothing to do with when the commands
contained in that line are executed.

As Peng partially demonstrated, any long compound command (e.g. a
function definition, or a while loop) is read all at once, before
any execution happens. set -v shows you the shell reading the lines
of the script. So what? It's not executing them. It's just reading
them. It doesn't reveal any useful information.

Adding echo/printf commands to show the contents of variables (or the
simple fact that execution has reached a specific point) is a useful tool,
and you should continue doing so wherever it's helpful. This is similar
to how set -x helps you -- it shows you what the shell is actually doing.

"declare -p varname" is also useful for showing the contents of
variables in many cases. In a very small number of cases, even that
may not reveal enough information, and then something like

printf %s "$varname" | od -c -An

(or your favorite hexdumper) may be what's needed.
Mike McClain
2018-06-14 00:51:22 UTC
Permalink
Post by Greg Wooledge
Post by Mike McClain
Post by Greg Wooledge
Post by Peng Yu
-v Print shell input lines as they are read.
Which is almost entirely useless. It doesn't help you debug a script.
I don't know why people keep trying to use it.
I could see it maybe possibly helping Chet debug bash. But not a script.
Hi Greg,
While I don't doubt for a minute that you know what you're talking
about, I don't.
How is this different than an echo ""? The bash version of the
proverbial 'print statement' used by programmers everywhere?
Bash (and sh) has two different "debug" options: -x and -v.
set -x tells bash (or sh) to print each command as it is being
*executed*, showing parameter expansions. It is a useful tool.
set -v tells bash (or sh) to print each *line* of the script as it
is being *read*. But this is not useful, because the point at which
a line of input is read has nothing to do with when the commands
contained in that line are executed.
As Peng partially demonstrated, any long compound command (e.g. a
function definition, or a while loop) is read all at once, before
any execution happens. set -v shows you the shell reading the lines
of the script. So what? It's not executing them. It's just reading
them. It doesn't reveal any useful information.
Adding echo/printf commands to show the contents of variables (or the
simple fact that execution has reached a specific point) is a useful tool,
and you should continue doing so wherever it's helpful. This is similar
to how set -x helps you -- it shows you what the shell is actually doing.
"declare -p varname" is also useful for showing the contents of
variables in many cases. In a very small number of cases, even that
may not reveal enough information, and then something like
printf %s "$varname" | od -c -An
(or your favorite hexdumper) may be what's needed.
That's a very clear explanation.
Thank you,
Mike
--
It's not always polite to speak your mind.

Loading...