Tee重置退出状态始终为0

时间:2016-03-07 11:31:54

标签: bash shell wait tee

我有一个像这样的简短剧本:

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

无论some_process的退出状态如何,结果始终为0。

我知道PIPESTATUS可以在这里使用,但为什么打破 wait

3 个答案:

答案 0 :(得分:3)

嗯,出于一些特殊的原因,这些文件并没有提及。但是,代码确实:

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);

所以它实际上在等待整个工作,正如我们所知,这通常会产生链中最后一个命令的退出状态。

更糟糕的是,$PIPESTATUS只能与最后的前景命令一起使用。

但是,您可以在子shell作业中使用$PIPESTATUS,如下所示:

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

答案 1 :(得分:0)

这里的诀窍是使用 $PIPESTATUS,还有wait -n

检查此示例:

#!/bin/bash

# start background task
(sleep 5 | false | tee -a /tmp/some.log ; exit ${PIPESTATUS[1]}) &

# foreground code comes here
echo "foo"

# wait for background task to finish
wait -n
echo $?

答案 2 :(得分:0)

您始终获得退出状态0的原因是退出的退出状态是管道中最后一个命令的退出状态,即tee。通过使用管道,您可以消除<some_command>退出状态的正常检测。

来自bash手册页:

  

管道的返回状态是最后一个命令的退出状态,除非启用了pipefail选项。如果启用了pipefail,则管道的返回状态是以非零状态退出的最后(最右侧)命令的值,如果所有命令都成功退出,则返回零。

所以...以下可能是你想要的:

#!/usr/bin/env bash

set -o pipefail
<some_command> | tee -a /tmp/some.log  &
wait %1
echo $?