3

Within a Bash script, if I run a command within a pipe the special parameter $? will contain the return code of the last command in the pipe. For instance, with an intentionally failing rsync command, I get the return code of the tee command:

$ rsync /non-existent-dir/ /another-dir2/ 2>&1 | tee outfile1 > outfile2
$ echo $?
0

I can get the return code of the rsync command by using the first entry in the special array which contains the return codes of the last pipe $PIPESTATUS

$ rsync /non-existent-dir/ /another-dir2/ 2>&1 | tee outfile1 > outfile2
$ echo ${PIPESTATUS[0]}
23

Normally if I background a task, I can use wait to collect its return code, as wait will mirror the return code of the background task it's waiting for.

$ rsync /non-existent-dir/ /another-dir2/ 2>&1 > outfile1 &
$ wait $!
$ echo $?
23

I can't seem to combine these two methods to capture the return code if the background process includes a pipe? I have a feeling that combining the methods is not the way to do this, and I need to use a different approach.

How do I execute a command like the following, and collect the return code of the first command?

$ rsync /non-existent-dir/ /another-dir2/ 2>&1 | tee outfile1 > outfile2 &
Arronical
  • 19,893

1 Answers1

0

You can access the PIPESTATUS variable inside the background process:

$ { rsync /non-existent-dir/ /another-dir2/ 2>&1 | tee outfile1 > outfile2 ; echo $PIPESTATUS } &

If you only want to know the exit status of the rsync command, you can simply use exit ${PIPESTATUS[0]} instead of the echo command. Otherwise you will have to use a temp file.

Reference: https://stackoverflow.com/a/50754377/13534737