+g...@wooledge.org On Wed, Jul 24, 2024 at 8:53 PM Mor Shalev <morsha...@google.com> wrote:
> 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 <g...@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. >> >