| Summary: | `sh -e' doesn't parse multi-command lines correctly | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Andrew Arensburger <arensb> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.2-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
I confirmed that ksh works as expected and the sh on Solaris works as
expected,
so I poked around and I have included a patch below. What it looks like
is that
for a semicolon node, evaltree() calls evaltree() for both sides of the
node and
then retests the eflag, even though it has already been tested on each
side of
the node. There is no reason, that I can see, for the semicolon node to
check
the eflag, so I just made it do the other tests and return.
--- /usr/src/bin/sh/eval.c.orig Thu Aug 5 23:08:44 1999
+++ /usr/src/bin/sh/eval.c Thu Aug 5 23:13:31 1999
@@ -200,10 +200,14 @@
switch (n->type) {
case NSEMI:
evaltree(n->nbinary.ch1, 0);
- if (evalskip)
- goto out;
- evaltree(n->nbinary.ch2, flags);
- break;
+ if (!evalskip) {
+ evaltree(n->nbinary.ch2, flags);
+ }
+ if (pendingsigs)
+ dotrap();
+ if (flags & EV_EXIT)
+ exitshell(exitstatus);
+ return;
case NAND:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus != 0) {
-- Danny J. Zerkel
dzerkel@columbus.rr.com
On Thu, 05 Aug 1999 23:20:12 EDT, "Danny J. Zerkel" wrote: > What it looks like > is that > for a semicolon node, evaltree() calls evaltree() for both sides of the > node and > then retests the eflag, even though it has already been tested on each > side of > the node. There is no reason, that I can see, for the semicolon node to > check > the eflag, so I just made it do the other tests and return. This patch works for me. While it's not as elegant as I would have liked (but I tend to be anal), I haven't been able to come up with a better solution. Theoretically, this patch might change the behavior of /bin/sh if you ever wound up with a tree of the form NAND / \ NSEMI stmt / \ stmt stmt but this can't happen, can it? -- Andrew Arensburger, Systems guy Center for Automation Research arensb@cfar.umd.edu University of Maryland Now we dolly back, now we fade to black... and roll credits! Some other fix has been applied, which also fixes this problem. This PR can be closed ------------------ dzerkel@columbus.rr.com State Changed From-To: open->closed As "Danny J. Zerkel" <dzerkel@columbus.rr.com> points out this has been fixed. Thanks. |
sh(1) says, : -e errexit : If not interactive, exit immediately if any untested command : fails. The exit status of a command is considered to be explic- : itly tested if the command is used to control an if, elif, while, : or until; or if the command is the left hand operand of an ``&&'' : or ``||'' operator. This works fine if the script is of the form cmd1 cmd2 && cmd3 but not if it is of the form cmd1; cmd2 && cmd3 One practical upshot is that if you have a Makefile built with GNU automake, "make clean" does not work. Fix: Don't know. If I come up with one, I'll let you know. How-To-Repeat: The following two scripts should behave identically: #!/bin/sh -e echo before test foo = bar && echo blah echo after #!/bin/sh -e echo before; test foo = bar && echo blah echo after The first one prints before after as expected. The second one, however, prints before and exits.