使用管道和tee命令获取命令在后台运行的返回值

时间:2016-07-27 09:10:11

标签: linux bash shell

我想获得命令在后台使用管道运行的返回值,所以我有以下示例代码。

#!/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"

输出:

Return Value of ls is 0 // It should print value 2

如果我从同一个命令回显返回值,则会打印正确的返回值。

但是如果将它存储在RETVALUE变量中,那么它会显示错误的值。

1 个答案:

答案 0 :(得分:4)

问题在于&标志。这会将RETVALUE赋值放入后台,因此该命令在与当前脚本不同的环境中执行,因此脚本中的变量不会更新。

您也不需要导出RETVALUE。 此外,wait命令不是必需的,因为bash在完成上一个命令之前不会处理下一个命令(除非你使用&将它放在后台)

#!/bin/bash

RETVALUE="0"
CMD='ls ThisFileDoesNotExit'
LOG='tee -a log.txt'
$CMD | $LOG
RETVALUE=${PIPESTATUS[0]}
echo "Return Value of ls is $RETVALUE"

编辑:如果您需要在后台启动该过程,您将被迫创建一个新脚本以恢复PIPESTATUS值,因为此变量是易失性的。可能的解决方案是:

#!/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"