Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange change between bash-3.2 and bash-4.0

1 view
Skip to first unread message

Roman Rakus

unread,
Feb 10, 2009, 7:42:32 AM2/10/09
to bug-...@gnu.org
Hi
there is simple script:
#!/bin/sh
echo foo|cat /nosuchfile
echo "here: $?"

executed by sh -e
In bash-3.2 we got:
cat: /nosuchfile: No such file or directory

but in bash-4.0:
cat: /nosuchfile: No such file or directory
here: 1


From execute_cmd.c:

/* 10/6/2008 -- added test for pipe_in and pipe_out because they indicate
the presence of a pipeline, and (until Posix changes things), a
pipeline failure should not cause the parent shell to exit on an
unsuccessful return status, even in the presence of errexit.. */

I'm not sure what Posix says

but it breaks the:
-e Exit immediately if a command exits with a non-zero status.

For reference see https://bugzilla.redhat.com/show_bug.cgi?id=483385

The fix:
diff -up bash-4.0-rc1/execute_cmd.c.err bash-4.0-rc1/execute_cmd.c
--- bash-4.0-rc1/execute_cmd.c.err 2009-01-31 20:05:38.000000000 +0200
+++ bash-4.0-rc1/execute_cmd.c 2009-01-31 20:05:46.000000000 +0200
@@ -764,7 +764,7 @@ execute_command_internal (command, async

if (ignore_return == 0 && invert == 0 &&
((posixly_correct && interactive == 0 && special_builtin_failed) ||
- (exit_immediately_on_error && pipe_in == NO_PIPE && pipe_out ==
NO_PIPE && exec_result != EXECUTION_SUCCESS)))
+ (exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)))
{
last_command_exit_value = exec_result;
run_pending_traps ();


RR


Roman Rakus

unread,
Feb 10, 2009, 8:13:30 AM2/10/09
to bug-...@gnu.org
If this stays as it is, bash will never exit immediately if a command
(in this case pipeline) exits with a non-zero status.
RR


Chet Ramey

unread,
Feb 10, 2009, 9:21:23 AM2/10/09
to Roman Rakus, bug-...@gnu.org, chet....@case.edu
Roman Rakus wrote:
> Hi
> there is simple script:
> #!/bin/sh
> echo foo|cat /nosuchfile
> echo "here: $?"
>
> executed by sh -e
> In bash-3.2 we got:
> cat: /nosuchfile: No such file or directory
>
> but in bash-4.0:
> cat: /nosuchfile: No such file or directory
> here: 1

The bash-4.0 behavior is correct; the previous behavior was a bug.

> From execute_cmd.c:
>
> /* 10/6/2008 -- added test for pipe_in and pipe_out because they indicate
> the presence of a pipeline, and (until Posix changes things), a
> pipeline failure should not cause the parent shell to exit on an
> unsuccessful return status, even in the presence of errexit.. */
>
> I'm not sure what Posix says

Posix says that only simple command failure should cause the shell to exit,
with several exceptions that are listed in the standard. A pipeline is
not a simple command.

That means that a pipeline failure doesn't cause the shell to exit, and
the failure of any individual simple command within a pipeline should not
cause the parent shell to exit. Even if the child process running the
pipeline element inherits the errexit flag, the fact that it exits should
not affect the parent shell. (The bug was that only a non-zero exit status
in the *final* pipeline element caused the parent shell to exit.)

> but it breaks the:
> -e Exit immediately if a command exits with a non-zero status.

I'm not immediately sure where you got that, but the documentation makes
it clear:

-e Exit immediately if a simple command (see SHELL GRAMMAR
above) exits with a non-zero status. The shell does not
exit if the command that fails is part of the command
list immediately following a while or until keyword,
part of the test in an if statement, part of a && or ||
list, or if the command's return value is being inverted
via !. A trap on ERR, if set, is executed before the
shell exits.


Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer

Chet Ramey, ITS, CWRU ch...@case.edu http://cnswww.cns.cwru.edu/~chet/


Chet Ramey

unread,
Feb 10, 2009, 9:49:22 AM2/10/09
to Roman Rakus, bug-...@gnu.org, chet....@case.edu
Roman Rakus wrote:

> If this stays as it is, bash will never exit immediately if a command

> (in this case pipeline) exits with a non-zero status.

That's clearly not true. Bash will not exit if a pipeline fails, but
will do so if a simple command fails.

Roman Rakus

unread,
Feb 10, 2009, 11:51:53 AM2/10/09
to chet....@case.edu, bug-...@gnu.org
Chet Ramey wrote:
> Roman Rakus wrote:
>
>
>> If this stays as it is, bash will never exit immediately if a command
>> (in this case pipeline) exits with a non-zero status.
>>
>
> That's clearly not true. Bash will not exit if a pipeline fails, but
> will do so if a simple command fails.
>
>
Isn't it the same? :) I agree with you.
RR


Roman Rakus

unread,
Feb 10, 2009, 12:07:31 PM2/10/09
to chet....@case.edu, bug-...@gnu.org
Chet Ramey wrote:
> Roman Rakus wrote:
>
This looks like Posix is not clear as it should be.
In Posix:

-e
When this option is on, if a simple command fails for any of the reasons
listed in Consequences of Shell Errors or returns an exit status value >0, and
is not part of the compound list following a while, until, or if keyword, and
is not a part of an AND or OR list, and is not a pipeline preceded by the !
reserved word, then the shell shall immediately exit.


They are
talking about simple commands, but later the words `is not a pipeline preceded
by the ! reserved word' makes no sense, if they are talking only about simple
commands...


So I understand that this is meant in bash this way.
RR


Chet Ramey

unread,
Feb 10, 2009, 5:35:29 PM2/10/09
to rra...@redhat.com, bug-...@gnu.org, chet....@case.edu
> -e
> When this option is on, if a simple command fails for any of the reasons
> listed in Consequences of Shell Errors or returns an exit status value >0, and
> is not part of the compound list following a while, until, or if keyword, and
> is not a part of an AND or OR list, and is not a pipeline preceded by the !
> reserved word, then the shell shall immediately exit.
>
>
> They are
> talking about simple commands, but later the words `is not a pipeline preceded
> by the ! reserved word' makes no sense, if they are talking only about simple
> commands...

That wording ("is not a pipeline") is intended to keep things like `! false'
from exiting the shell. A simple command is a "degenerate" pipeline, and
the `!' reserved word applies only to pipelines.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer

Chet Ramey, ITS, CWRU ch...@case.edu http://tiswww.tis.case.edu/~chet/


Sitaram Chamarty

unread,
Feb 11, 2009, 3:20:40 AM2/11/09
to bug-...@gnu.org
On 2009-02-10, Chet Ramey <chet....@case.edu> wrote:
> I'm not immediately sure where you got that, but the documentation makes
> it clear:
>
> -e Exit immediately if a simple command (see SHELL GRAMMAR
> above) exits with a non-zero status. The shell does not
> exit if the command that fails is part of the command
> list immediately following a while or until keyword,
> part of the test in an if statement, part of a && or ||
> list, or if the command's return value is being inverted
> via !. A trap on ERR, if set, is executed before the
> shell exits.

Could it perhaps be amended to explicitly exclude pipes,
along with all the other exclusions listed?

Until now I thought a pipe would also cause an exit if it
failed.

In a way, it might have been better if the documentation had
stopped at the first sentence.

But by explicitly listing some exclusions, it made me think
I don't really need to go lookup what precisely is a simple
command.

Just a suggestion...

Archimerged Ark Submedes

unread,
Feb 11, 2009, 4:16:20 AM2/11/09
to bug-bash
Ulrich Drepper in comment 6 to redhat bug 483385 links to
austin-group-l, item 11863 by Geoff Clare:

https://bugzilla.redhat.com/show_bug.cgi?id=483385#c6
https://www.opengroup.org/sophocles/show_mail.tpl?CALLER=index.tpl&source=L&listname=austin-group-l&id=11863


Geoff Clare writes: [...]

I think the description of -e should be replaced by:

-e When this option is on, if either
* a pipeline, or
* a simple command that is not in a pipeline
fails for any of the reasons listed in Section 2.8.1 (on page
2315) or returns an exit status value >0, and is not part of


the compound list following a while, until, or if keyword, and
is not a part of an AND or OR list, and is not a pipeline

beginning with the ! reserved word, then the shell shall
immediately exit.

--
Geoff Clare <yyyyyyy@xxxxxxxxxxxxx>
The Open Group, Thames Tower, Station Road, Reading, RG1 1LX, England


0 new messages