I want to get the return value of command run in background with pipe so i have below sample code.
#!/bin/bash export RETVALUE="0" CMD='ls ThisFileDoesNotExit' LOG='tee -a log.txt' $CMD | $LOG ; RETVALUE=${PIPESTATUS[0]} & #$CMD | $LOG ; echo ${PIPESTATUS[0]} & // This print ret value 2 wait echo "Return Value of ls is $RETVALUE"
Output:
Return Value of ls is 0 // It should print value 2
If i echo the return value from same command then it print correct return value.
But if store it in RETVALUE variable then it shows wrong value.
Advertisement
Answer
The problem is due to the & sign. This puts the RETVALUE assignment into the background, thus this command executes in a different environment than the current script, so the variables in your script do no get updated.
You also don’t need to export the RETVALUE.
Also the wait
command is not necessary, as bash does not process the next command until it has finished the previous one (unless you use the & to put it in the background)
#!/bin/bash RETVALUE="0" CMD='ls ThisFileDoesNotExit' LOG='tee -a log.txt' $CMD | $LOG RETVALUE=${PIPESTATUS[0]} echo "Return Value of ls is $RETVALUE"
EDIT: If you need to launch the process in the background, you will be forced to create a new script in order to recover the PIPESTATUS value, due to this variable is volatile. A possible solution is:
#!/bin/bash CMD='ls ThisFileDoesNotExit' LOG='tee -a log.txt' TMPSCRIPT="file1.sh" echo '#!/bin/bash' > $TMPSCRIPT echo "$CMD |$LOG" >> $TMPSCRIPT echo 'exit ${PIPESTATUS[0]}' >> $TMPSCRIPT chmod +x $TMPSCRIPT ./$TMPSCRIPT & MYPID=$! wait $MYPID RETVALUE=$? rm $TMPSCRIPT echo "Return Value of ls is $RETVALUE"