Hi,

On 01/09/2021 14:38, Oğuz via austin-group-l at The Open Group wrote:
Consider the following:

true
a=$? b=`exit 1` b=$? >`echo /dev/null; exit 2`
echo $? $a $b

Having read the relevant sections of the standard a couple times, I
would expect the output to be `1 0 0';

I agree.

                                       but that's not the case with
most shells. Below are what each shell I have on my computer output
for that script.

         ?  a  b
bash    2  0  1
bosh    2  0  0
dash    1  0  0
ksh     2  0  1
mksh    1  0  0
yash    2  0  0
zsh     1  2  1

Now, I wonder, what did I miss? Where does it say in the standard that
the value of parameter `?' is affected by redirections, and that its
value depends on assignments that appear earlier in the same command?

There are two problems here. The first is the value of $? during expansion. The standard says:

  If there is no command name, but the command contained a command
  substitution, the command shall complete with the exit status of the
  last command substitution performed. Otherwise, the command shall
  complete with a zero exit status.

Some shells implement this by modifying $? as soon as a command substitution finishes. As all command substitutions are processed in order, the end result is that $? is based on the last command substitution performed. However, there is nothing that allows $? to be modified earlier, so this looks like a bug (#1) in those shells.

The second problem is the redirection. Based on the above, command substitutions in a redirection are supposed to affect the exit status just as any other command substitution, but the standard says:

  3. Redirections shall be performed as described in Redirection.

  4. Each variable assignment shall be expanded for tilde expansion,
     parameter expansion, command substitution, arithmetic expansion,
     and quote removal prior to assigning the value.

This means the command substitution in your redirection is supposed to be performed prior to that in the variable assignment. Some shells do not do this in the specified order, which looks like a bug (#2) in those shells. This can be confirmed by running under 'set -x'.

Bug #1 leads to the output "1 2 1".
Bug #2 leads to the output "2 0 0".
Bug #1 & bug #2 combined leads to the output "2 0 1".

Cheers,
Harald van Dijk

  • $? in a simple comman... Oğuz via austin-group-l at The Open Group
    • Re: $? in a simp... Harald van Dijk via austin-group-l at The Open Group
      • Re: $? in a ... Geoff Clare via austin-group-l at The Open Group
        • Re: $? i... Harald van Dijk via austin-group-l at The Open Group
    • Re: $? in a simp... Robert Elz via austin-group-l at The Open Group
      • Re: $? in a ... Oğuz via austin-group-l at The Open Group
      • Re: $? in a ... Harald van Dijk via austin-group-l at The Open Group
      • Re: $? in a ... Robert Elz via austin-group-l at The Open Group
        • Re: $? i... Chet Ramey via austin-group-l at The Open Group
          • Re: ... Joerg Schilling via austin-group-l at The Open Group
            • ... Scott Lurndal via austin-group-l at The Open Group
              • ... Joerg Schilling via austin-group-l at The Open Group

Reply via email to