>>>>> 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.