[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: if source command.sh & set -e issue
From: |
Mor Shalev |
Subject: |
Re: if source command.sh & set -e issue |
Date: |
Wed, 24 Jul 2024 20:53:33 +0300 |
Hi Greg,
Thanks a lot for your detailed response.
You are right, I meant "as I expected".
The else in my example was redundant.
Let's say we remain with:
*if source command.sh ; then echo passfi*
Or, similarly:
*source command.sh && echo pass*
looking at the following:
morshalev@morsh:~/workspace1/soc/soc> cat script.sh
#!/bin/bash
(source command.sh) && echo pass
morshalev@morsh:~/workspace1/soc/soc> cat command.sh
#!/bin/bash
set -e
echo calling tool a
echo calling tool b
false
echo calling tool c
echo calling tool d
*in 4.2 we get:*morshalev@morshalev:~/workspace16/soc2> ./script.sh
calling tool a
calling tool b
*in 4.4 we get:*
morshalev@morsh:~/workspace1/soc/soc> ./script.sh
calling tool a
calling tool b
calling tool c
calling tool d
pass
and we get the same result in 4.4 also when adding 'set -e' to script.sh:
morshalev@morsh:~/workspace1/soc/soc> cat ./script.sh
#!/bin/bash
*set -e*source command.sh && echo pass
morshalev@morsh:~/workspace1/soc/soc> ./script.sh
calling tool a
calling tool b
calling tool c
calling tool d
pass
Thanks!
On Wed, Jul 24, 2024 at 6:56 PM Greg Wooledge <greg@wooledge.org> wrote:
> On Wed, Jul 24, 2024 at 16:23:35 +0300, Mor Shalev via Bug reports for the
> GNU Bourne Again SHell wrote:
> > script.sh contain:
> > if source command.sh ; then
> > echo pass
> > else
> > echo fail
> > fi
> > command.sh contain 'set -e' at start. so command.sh should exit once
> detect
> > fail.
> >
> > once calling ./script.sh it looks like command.sh dont handle 'set -e'
> > correctly and it continues the script till the end anyway. (btw, it works
> > correctly at version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
>
> Words like "correctly" lose all their meaning when set -e enters the
> picture. I think what you really meant is "as I expected".
>
> set -e *rarely* works as one expects.
>
> Reproducing what I think you're doing:
>
> hobbit:~$ cat script.sh
> #!/bin/bash
> if source command.sh ; then
> echo pass
> else
> echo fail
> fi
> false
> echo ending script.sh
> hobbit:~$ cat command.sh
> set -e
> false
> echo still in command.sh
> hobbit:~$ ./script.sh
> still in command.sh
> pass
> hobbit:~$ bash-4.2 script.sh
> hobbit:~$ bash-5.0 script.sh
> still in command.sh
> pass
> hobbit:~$ bash-4.4 script.sh
> still in command.sh
> pass
> hobbit:~$ bash-4.3 script.sh
> still in command.sh
> pass
>
> So, it would appear that the behavior changed between 4.2 and 4.3. I'll
> let someone else try to dig up the reasoning behind the change. I'm more
> concerned with your misconceptions about set -e.
>
> Your bug report implies that you believe "command.sh" is a separate
> script, which can "exit". But this isn't the case. You're reading the
> lines of command.sh within the same shell process that's reading the
> parent ./script.sh.
>
> If command.sh were actually to run an "exit" command, your entire script
> would exit, not just command.sh. If you want to terminate the sourced
> file but *not* the whole script, you'd need to use "return" instead of
> "exit".
>
> Moreover, since you've run "set -e" inside a sourced file, this turns
> on set -e for your whole script. If you examine $- after the source
> command returns, you'll see that it contains "e".
>
> Now, look once more at how bash 4.2 behaved:
>
> hobbit:~$ bash-4.2 script.sh
> hobbit:~$
>
> There's no output at all. Neither "pass" nor "fail" -- because the
> entire script exited. Presumably as a result of the "false" command
> inside command.sh, after set -e had been turned on.
>
> Is that *really* what you wanted? It certainly doesn't sound like it,
> based on your bug report.
>