Re: set -e not ignored in AND-OR list

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

 



On 10/11/2024 18:58, Christoph Anton Mitterer wrote:
On Sun, 2024-11-10 at 17:06 +0000, Harald van Dijk wrote:
In dash, the effect of 'set -e' in a
command
substitution is that a command is never considered "tested", unless
that
testing happens inside the command substitution, and it would be
useful
for that to be documented.

The way set -e is currently documented (with "tested" vs. "untested")
in the manpage is IMO already a bit strange.

The way that 'set -e' is currently documented would be useful, but does not match what is implemented.

Basically: what the current documentation is saying is that every command gets an implicit "|| exit $?" added to it, unless there is more specific error handling in the script.

But that is not what POSIX specifies, and what dash implements is closer to what POSIX specifies, but not exactly what POSIX specifies. The manpage suggests that

  $ dash -c '(set -e; false; echo 123) && echo 456'

would output nothing. Of course, what happens instead, in all shells that I know of, is that this prints "123" followed by "456".

By POSIX's wording, that's right: "The -e setting shall be ignored when executing [...] any command of an AND-OR list other than the last." and there is no denying that that subshell is executing.

By dash's wording that's wrong: the "false" command is not the left hand operand of an "&&" operator, it's only *part of* the left hand operand of an "&&" operator.

My personal first preference, which I realise will not and should not be implemented because it disregards POSIX, would be to leave the documentation as it is, and adjust dash's behaviour to match the documentation.

Adjusting the documentation to match the current implementation would be my personal second choice.

But your text makes it rather even more complicated O:-D

What about something like:
  The exit status of a command
+(excluding any commands within command substitutions therein)
  is considered to be explicitly tested if the
  command is  used to control an if, elif

or so...?!

I think the current behaviour would be covered by:

The exit status of a command is considered to be explicitly 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; or if the command is part of a list of which the exit status is tested.

I mean AFAIU set -e is NOT ignored only for the commands IN the command
substitution, but IS still ignored for the overall result of the
command substitution (as part of an if, while, etc.).

Correct, 'set -e' is in full effect during command substitutions.

$ dash -ec 'var=$(false; echo foo) || echo foo; var=$(false; echo bar); echo bar'
 foo

Here, the list 'false; echo foo' is (arguably contrary to POSIX) not considered the LHS of an "||" operator, therefore 'false' causes the whole subshell to exit, the 'var=$(false; echo foo)' command is considered to fail, but that command has its exit status tested so execution continues.

Likewise, the 'var=$(false; echo bar)' command is considered to fail, that command does not have its exit status tested, so execution stops.

If it's however long standing behaviour of dash (and perhaps
others),
maybe POSIX should instead be revised.

Yes, that would be my preference.

Another "downside" of allowing command substitutions to ignore the
ignoring of set -e is however that things get even more complicated.

I mean it's already crazy enough that for pipelines only the ! negated
ones and for AND-OR lists only all but the last elements are affected
by the set -e ignoring.
Generally excluding command substitutions from all these cases would
make it even more complex to understand and easy to forget while
coding.

IMHO, what dash's manpage currently states is clear and useful, and if that were actually implemented, the fact that it does not affect subshells would be a natural consequence, not a special exception.

The difference between treatment of subshells in command substitutions and subshells outside of command substitutions does make it more complicated to understand though.

Cheers,
Harald van Dijk




[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux