while loop with extdebug + debug trap always returning 1

2017-04-04 Thread nesro
Hi bash-bug,

I think I've found a bug in bash.

I'm working on a project that skips** all commands that are going to be
executed. I achieved this by a combination of a debug trap and extdebug.
Once,
for the entire list of commands to be executed, I'm going to execute it via
eval
from the debug trap. It works surprisingly well and it opens a possibility
of
really cool things.

**Excerpt from man bash extdebug: "If the command run by the DEBUG trap
returns
a nonzero value, the next command is skipped and not executed."

I found out that the while cycle is not working, but the for cycle is. Which
made me think that I found a bug in bash.

There are the instructions to reproduce the bug:


# create a new shell
bash --norc


# set up xtrace to see what's happening (not mandatory for reproduction)
set -x


# set up the debug trap with extdebug so that every command is not executed
# (be sure to close and reopen the shell, because trying to set it
differently
# will not work)
t() { return 1; }
trap t DEBUG
shopt -s extdebug


# run an empty for cycle. we can see from the output that bash ran :, then
# false and stopped to it. which is the right behavior
for (( :; false; )); do :; done


# now run this while cycle. it just cycle the debug trap forever
while false; do :; done



I've tried it on two versions of bash under lubuntu gnu/linux:
- 4.3.46(1)-release
- 4.4.0(1)-release


Please let me know if I overlooked something, or if this really looks like
a bug.

Thank you,
Tomas Nesrovnal


Re: while loop with extdebug + debug trap always returning 1

2017-04-04 Thread nesro
Hi Martin,
thanks for reply.

> > # run an empty for cycle. we can see from the output that bash ran :,
then
> > # false and stopped to it. which is the right behavior
> > for (( :; false; )); do :; done
>
> This is a syntax error. 'for' takes arithmetic expressions, not shell
> commands.

Sorry, my bad. I just wanted to make the command as simple as possible to
demonstrate the order of execution and I didn't notice that I got into an
invalid command. It's the same with this, valid, command:

for (( ; 1 > 2; )); do :; done


> > # now run this while cycle. it just cycle the debug trap forever
> > while false; do :; done

> The 'false' command is never executed so never has the chance to return
> an exit status of "false" (1).

To have both commands similar, let's assume the while as this:

while (( 1 > 2 )); do :; done

Thanks for explaining me why it happen, but now I don't know why for cycle
works and while does not.

The for cycle run the condition (after setting: t() { return 1; }; trap t
DEBUG; shopt -s extdebug)

bash-4.3$ for (( ; 1 > 2; )); do :; done
+ (( 1 ))
++ t
++ return 1
+ (( 1 > 2 ))
++ t
++ return 1

but the while cycle does not:

bash-4.3$ while (( 1 > 2 )); do :; done
++ t
++ return 1
++ t
++ return 1
.. loop forever ..


Is there any workaround to achieve the functionality I want? That is:
Prevent execution of everything by default. I will decide what to run by
using eval from the debug trap.

Thanks,
Tomas