Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

heads up: /bin/sh -e no longer disabled in command substitutions

If we run the following command

  $SHELL -ce 'printf %s\\n "${SHELL##*/}: $- ($-) \$($(printf %s $-))"'

with SHELL set to invoke a bunch of different shells, we can see the
settings of the options - and particularly the 'e' option in three
contexts - as it is in the top level shell, in a subshell, and in
a command substitution.

Here are some results:

fbsh: e (e) $(e)
dash: e (e) $(e)
bosh: es (es) $(es)
pbosh: es (es) $(es)
zsh: 569Xe (569Xe) $(569Xe)
yash: ce (ce) $(ce)
ksh: ceh (ceh) $(ceh)
mksh: ehc (ehc) $(ehc)
oksh: ceh (ceh) $(ceh)
pdksh: ceh (ceh) $(ceh)
ksh93: cehsB (cehsB) $(cehsB)

What other options are set by default isn't what's important here,
what is, is that the same set of options appears in all three
contexts - which is as it should be, nothing changed them.

When I test our sh:

sh: eL (eL) $(L)

Note that the 'e' option has mysteriously turned off in the
command substitution.   (For those who have an interest, the 'L'
option relates to how $LINENO works in functions.)

That happens explicitly in our sh - whenever a command substitution
is started, the 'e' option is disabled.   The code for that was included
in a patch set (taken from what is now dash - though I believe it had
not yet acquired that name) back in early 2000 - these were the patches
that fixed a number of "sh -e" PRs, that made sh -e mostly correct in
the NetBSD sh (there have been later changes that made it even better).

I have just removed (from /bin/sh in HEAD) the one line of code that
turns off the 'e' flag in a command substitution (in the command
substitution subshell).

Note: there are no changes here to the way -e works when enabled - only
to whether it is turned on or not in that one case.

Watch for any odd behaviour from scripts or makefiles - there really
should be none.   Let me know if something breaks which might be


ps: you may have noticed that I omitted bash from the tests above.
That's because it has a foot in each camp, in default mode it acts
as our shell did:

bash: ehBc (ehBc) $(hBc)

but not when in posix mode (bash -o posix):

bash: ehBc (ehBc) $(ehBc)

It seems that sometime, long ago (last century/millennium) there was a
belief somewhere, that -e should be turned off in command substitutions.
The (not yet called) dash of the time evidently did that, which is from
where we got that.   bash apparently did it as well.   Perhaps some other
shells.   Everyone else (if they ever did this) stopped it long ago.
bash is, however, big on backwards compat (as are we in general) and
changes to ancient code don't get made to the default mode if there's
any possibility someone might be relying upon it.

Home | Main Index | Thread Index | Old Index