>>>>> On Tue, 10 Dec 2024, Greg Wooledge wrote:
> My own testing:
> hobbit:~$ if true; then (exit 11) | cat; fi
> hobbit:~$ echo "$? ${PIPESTATUS[*]}"
> 0 11 0
> hobbit:~$ if true; then (exit 11) | cat; fi | false
> hobbit:~$ echo "$? ${PIPESTATUS[*]}"
> 1 0 1
> hobbit:~$ while (exit 12); do :; done
> hobbit:~$ echo "$? ${PIPESTATUS[*]}"
> 0 12
> hobbit:~$ true | while (exit 12); do :; done
> hobbit:~$ echo "$? ${PIPESTATUS[*]}"
> 0 0 0
> Given all that we've tried here, all I can determine is:
> 1) If an "if", "case" or "while" (and probably "until" too) is executed
> by itself as the sole command in a pipeline, the compound command sets
> the value of $? but not the value of PIPESTATUS. It doesn't matter
> whether the "body" is entered.
> 2) If the same command appears as part of a pipeline with other commands
> in it, then the compound command's exit status does become part of
> PIPESTATUS.
Yes, this seems to be a reasonable conclusion.
> It's hard to see how this is anything other than a bug. But it's an
> incredibly long-standing behavior -- all the way back to 2.05b or
> earlier. Given that PIPESTATUS is a bash extension, not part of POSIX,
> it's up to Chet to decide what to do about it.
Maybe looking at another shell is also useful?
With mksh 59c and your above examples, I get:
mksh $ if true; then (exit 11) | cat; fi
mksh $ echo "$? ${PIPESTATUS[*]}"
0 11 0
mksh $ if true; then (exit 11) | cat; fi | false
mksh $ echo "$? ${PIPESTATUS[*]}"
1 0 1
mksh $ while (exit 12); do :; done
mksh $ echo "$? ${PIPESTATUS[*]}"
0 0
mksh $ true | while (exit 12); do :; done
mksh $ echo "$? ${PIPESTATUS[*]}"
0 0 0
Also, for my previously reported test cases:
mksh $ if false; then :; fi
mksh $ echo "ret = $?, status = ${PIPESTATUS[*]}"
ret = 0, status = 0
mksh $ true; case a in esac
mksh $ echo "ret = $?, status = ${PIPESTATUS[*]}"
ret = 0, status = 0
mksh $ false; case a in esac
mksh $ echo "ret = $?, status = ${PIPESTATUS[*]}"
ret = 0, status = 0
All these results are what I would (naively?) expect them to be.