Search code examples
bashshellwaittee

Tee resets exit status is always 0


I have a short script like this:

#!/bin/bash
<some_process> | tee -a /tmp/some.log  &
wait $(pidof <some_process_name>)
echo $?

The result is always 0, irrespective of the exit status of some_process.

I know PIPESTATUS can be used here, but why does tee break wait?


Solution

  • Well, this is something that, for some peculiar reason, the docs don't mention. The code, however, does:

    int wait_for (pid) { /*...*/
    /* If this child is part of a job, then we are really waiting for the
    job to finish. Otherwise, we are waiting for the child to finish. [...] */
    
    if (job == NO_JOB)
      job = find_job (pid, 0, NULL);
    

    So it's actually waiting for the whole job, which, as we know, normally yields the exit status of the last command in the chain.

    To make matters worse, $PIPESTATUS can only be used with the last foreground command.

    You can, however, utilize $PIPESTATUS in a subshell job, like this:

    (<some_process> | tee -a /tmp/some.log; exit ${PIPESTATUS[0]}) &
    # somewhere down the line:
    wait %%<some_process>