zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Philippe Altherr <philippe.altherr@gmail.com>
Cc: "Lawrence Velázquez" <larryv@zsh.org>, zsh-workers@zsh.org
Subject: Re: Inconsistent behavior of ERR_EXIT with conditionals
Date: Tue, 8 Nov 2022 15:28:56 -0800	[thread overview]
Message-ID: <CAH+w=7ZkWP_O08ETh-UbOguXngACQPGS+Z9rwUCPVez8ZTq=gg@mail.gmail.com> (raw)
In-Reply-To: <CAGdYchvGratVkzg_n8CuT=e--QbDaEjT3PXFuyhbFhp8DJ5hQA@mail.gmail.com>

On Tue, Nov 8, 2022 at 10:51 AM Philippe Altherr
<philippe.altherr@gmail.com> wrote:
>
> Let me try to illustrate with a more concrete example why I think Zsh's behavior could/should be improved. Consider that a first developer wrote the following code:
>
>> #!/bin/zsh -e

The first developer is wrong.  That's not what -e is for.  A script
should be correct WITHOUT the use of -e ... the purpose of -e is to
uncover cases where the developer made a mistake, not to be an
integral part of the script function.

> On Tue, Nov 8, 2022, at 12:36 AM, Bart Schaefer wrote:
>>
>> ERR_EXIT kicks in only when the result is not otherwise checked.
>
> Unfortunately there are several cases where Zsh doesn't behave like that. For example, consider the following commands:
>
>> { false; true } || true; echo $?
>> if false; true; then echo 0; else echo 1; fi

Again, wrong.  "{ false; true }" is a single statement because of the
braces.  When that statement is followed by || the result of the
ENTIRE statement is considered to have been "checked".
Similarly, in "if false; true; then" the conditional part is
considered as a single statement whose result is "checked".

As Lawrence has said, you're discarding the POSIX definition of how
"set -e" is intended to work.

> There are other cases where ERR_EXIT is triggered but fails to propagate. A major offender in that regard is the following code:
>
>> local var=$(false); echo $?
>
> In this case "false" triggers an ERR_EXIT but it only exits the sub-shell of the command substitution.

This is explicitly called out in the documentation:

     Unlike parameter assignment statements, typeset's exit status on an
     assignment that involves a command substitution does not reflect
     the exit status of the command substitution.  Therefore, to test
     for an error in a command substitution, separate the declaration of
     the parameter from its initialization:

          # WRONG
          typeset var1=$(exit 1) || echo "Trouble with var1"

          # RIGHT
          typeset var1 && var1=$(exit 1) || echo "Trouble with var1"

> However, having to systematically use this style is rather cumbersome. Furthermore it's not even foolproof. Indeed, if there are multiple command substitutions, the assignment returns the exit status of the last one. Thus, the following command does NOT exit and prints "0":
>
>> local var; var=$(false)$(true); echo $?

This also follows bash and presumably POSIX behavior.

> Is there any chance that Zsh could be changed to more closely follow the specification above?

No.


  parent reply	other threads:[~2022-11-08 23:29 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04 16:37 Philippe Altherr
2022-11-06 20:45 ` Bart Schaefer
2022-11-07  3:50   ` Bart Schaefer
2022-11-07  5:35     ` [PATCH] " Bart Schaefer
2022-11-07  9:44       ` Peter Stephenson
2022-11-08  1:20         ` Bart Schaefer
2022-11-08  4:58     ` Philippe Altherr
2022-11-08  5:36       ` Bart Schaefer
2022-11-08  8:04         ` Lawrence Velázquez
2022-11-08 18:51           ` Philippe Altherr
2022-11-08 19:20             ` Lawrence Velázquez
2022-11-08 23:28             ` Bart Schaefer [this message]
2022-11-09  4:11               ` Philippe Altherr
2022-11-09  6:00                 ` Bart Schaefer
2022-11-09 14:22                   ` Philippe Altherr
2022-11-10  1:00                     ` Bart Schaefer
2022-11-10  5:09                       ` Bart Schaefer
2022-11-11  3:04                         ` Philippe Altherr
2022-11-11  4:06                           ` Lawrence Velázquez
2022-11-11  4:09                           ` Eric Cook
2022-11-08 23:11           ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7ZkWP_O08ETh-UbOguXngACQPGS+Z9rwUCPVez8ZTq=gg@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=larryv@zsh.org \
    --cc=philippe.altherr@gmail.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).