PIPESTATUS gets-reset-without-running-a-pipe

TLDR:

PIPESTATUS gets reset without running a pipe even if you set unrelated variable after you ran a pipe.

Example

GT-Sandbox-Snapshot: Example

Code

# Define a sample function for testing the behavior of PIPESTATUS
sample_command_that_fails() {
  echo ""
  echo 'Running Sample Command that fails (returns 1)...'
  return 1
}

# Temporary file for output capture
OUTPUT_FILE="/tmp/sample_output.txt"

correct(){
  sample_command_that_fails | tee "${OUTPUT_FILE:?}"
  echo.green "Pipe status captured as expected: ${PIPESTATUS[0]}"
}


incorrect(){
    sample_command_that_fails | tee "${OUTPUT_FILE:?}"
    SOME_VAR="${OUTPUT_FILE:?}"
    echo.yellow "Pipe status got reset without a PIPE call: ${PIPESTATUS[0]}"
}

main() {
  correct
  incorrect
}

main "${@}" || exit 1

Command to reproduce:

gt.sandbox.checkout.commit c4acfa9c4417db3671dc \
&& cd "${GT_SANDBOX_REPO}/bash" \
&& cmd.run.announce "./main.sh"

Recorded output of command:


Running Sample Command that fails (returns 1)...
Pipe status captured as expected: 1

Running Sample Command that fails (returns 1)...
Pipe status got reset without a PIPE call: 0

Explanation:

This makes sense when we look at definition of PIPESTATUS from Bash Manual:

PIPESTATUS : An array variable (see Arrays below) containing a list of exit status values from the processes in the most-recently-executed [foreground pipeline] (which may contain only a single command).