On Tue, Dec 10, 2024 at 09:28:31 +0100, Ulrich Müller wrote: > Then what about these? > > $ true; case a in esac > $ echo "ret = $?, status = ${PIPESTATUS[*]}" > ret = 0, status = 0 > > $ false; case a in esac > $ echo "ret = $?, status = ${PIPESTATUS[*]}" > ret = 0, status = 1 > > "case a in esac" is a one-command pipeline, and certainly it is executed > after "false". So it should qualify as "the most-recently-executed > foreground pipeline (which may contain only a single command)".
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. 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.