[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: if source command.sh & set -e issue
From: |
Greg Wooledge |
Subject: |
Re: if source command.sh & set -e issue |
Date: |
Wed, 24 Jul 2024 11:56:19 -0400 |
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.