Re: set -e not working as expected with conditional operators

2023-06-02 Thread Greg Wooledge
On Fri, Jun 02, 2023 at 09:01:11AM -0400, Chet Ramey wrote:
> On 6/1/23 9:01 PM, rpaufin1 wrote:
> > Consider the following script:
> > 
> > #!/bin/bash
> > 
> > f() {
> >  ls missing-file 2> /dev/null
> >  echo "test"
> > }
> > 
> > # 1
> > (set -e; f); ret=$?
> > if (( ret )); then
> >  echo "failed"
> >  exit 1
> > fi
> > 
> > # 2
> > (set -e; f) || {
> >  echo "failed"
> >  exit 1
> > }
> > 
> > Running the block labelled '1' prints "failed" and returns 1 as the exit 
> > code, while running the other block prints "test" and returns 0. However, 
> > the result should be the same.
> 
> It should not. The manual lists the instances where the shell does not
> exit if a command fails while -e is enabled, and and-or lists are one of
> those.

It's similar to example 4 on .

People are probably going to be surprised that the call to f in "block 2"
above is considered "part of an and-or list", because the and-or list
appears outside of the subshell.  I presume that the subshell inherits
the "I am inside an and-or list" flag from its parent process, and
doesn't clear it, and that this is intentional.

Examples like this continue to demonstrate why set -e should be avoided.



Re: set -e not working as expected with conditional operators

2023-06-02 Thread Chet Ramey

On 6/1/23 9:01 PM, rpaufin1 wrote:

Consider the following script:

#!/bin/bash

f() {
 ls missing-file 2> /dev/null
 echo "test"
}

# 1
(set -e; f); ret=$?
if (( ret )); then
 echo "failed"
 exit 1
fi

# 2
(set -e; f) || {
 echo "failed"
 exit 1
}

Running the block labelled '1' prints "failed" and returns 1 as the exit code, while 
running the other block prints "test" and returns 0. However, the result should be the 
same.


It should not. The manual lists the instances where the shell does not
exit if a command fails while -e is enabled, and and-or lists are one of
those.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/




Re: set -e not working as expected with conditional operators

2023-06-02 Thread Robert Elz
Date:Fri, 02 Jun 2023 01:01:08 +
From:rpaufin1 
Message-ID:  


  | What's going on here? I'm using the latest release, Bash 5.2.15.

Bash is doing what it it is supposed to be doing.   Just don't use -e
unless you are an expert in what it actually means, and once you're
that, you'd almost never consider using it in any normal script.   It
is intended for make to use, and nothing else (there are a few, very
unusual, cases where it can help - but if you script contains any logic
at all, it isn't one of those cases).

kre




Re: set -e not working as expected with conditional operators

2023-06-02 Thread Oğuz İsmail Uysal

On 6/2/23 4:01 AM, rpaufin1 wrote:

However, the result should be the same.

The manual says otherwise:
The shell does not exit if the command that fails is [...] part of any 
command executed in a && or || list except the command following the 
final && or ||





set -e not working as expected with conditional operators

2023-06-01 Thread rpaufin1
Consider the following script:

#!/bin/bash

f() {
ls missing-file 2> /dev/null
echo "test"
}

# 1
(set -e; f); ret=$?
if (( ret )); then
echo "failed"
exit 1
fi

# 2
(set -e; f) || {
echo "failed"
exit 1
}

Running the block labelled '1' prints "failed" and returns 1 as the exit code, 
while running the other block prints "test" and returns 0. However, the result 
should be the same.
If f() is modified like so, however:

f() {
ls missing-file 2> /dev/null || return 1
echo "test"
}

then it "works", but this also works without using set -e.

I thought this was an issue with subshells, but apparently the following script 
also doesn't work as expected:

#!/bin/bash

f() {
ls missing-file 2> /dev/null
echo "test"
}

set -e
f && :

Since f() is not ran in a subshell, the script should quit after the 'ls' 
command because of set -e, but "test" is still printed and the script exits 
with 0. To make this script work you can either remove the "&& :" part or the 
'echo' command from f(), but again, it doesn't seem like it's supposed to work 
this way.

# This works
f() {
ls missing-file 2> /dev/null
}
set -e
f && :

# This also works
f() {
ls missing-file 2> /dev/null
echo "test"
}
set -e
f

What's going on here? I'm using the latest release, Bash 5.2.15.