结果准备好后退出并且不等待其余工作?

时间:2016-03-25 17:08:47

标签: awk sleep exit head

我想在提供结果后立即退出,不要等待其余的工作。我通过不同的方法提供了三个例子,即awk,head和read。我想在以下示例中显示“1”后退出而不等待睡眠。但没有一个不起作用。有人帮我吗?

(echo 1; sleep 10; seq 10) | head -n 1
(echo 1; sleep 10; seq 10) | awk -e 'NR==1{print $1;exit}'
(echo 1; sleep 10; seq 10) | ./test.sh  

test.sh如下:

while read -r -d $'\n' x
do
    echo "$x"
    exit
done

1 个答案:

答案 0 :(得分:0)

使用Bash过程替换重构

  

我希望在以下示例中显示“1”后退出而不等待睡眠。

默认情况下,Bash shell pipelines等待每个管道段完成,然后再处理管道的下一个段。这通常是预期的行为,因为否则您的命令将无法对每个管道元素的已完成输出执行操作。例如,如果 sort 在一个管道中完成其工作,如果它没有一次可用的所有数据呢?

在这种特定情况下,您可以执行您想要的操作,但您必须重构代码,以便awk从process substitution而不是管道读取。例如:

$ time awk -e 'NR==1 {print $1; exit}' < <(echo 1; sleep 10; seq 10)
1

real    0m0.004s
user    0m0.001s
sys 0m0.002s

从时间上看,你可以看到当awk执行时进程退出。这可能不是你想要怎么做,但它确实会以最小的麻烦完成你想要完成的任务。使用非Bash外壳的里程可能会有所不同。

异步管道

异步管道实际上并不是一个通用的解决方案,但使用一个解决方案可以充分实现给定用例的目标。以下内容立即返回:

$ { echo 1 & sleep 10 & seq 10 & } | awk -e 'NR==1 {print $1; exit}'
1

因为command list中的命令是异步运行的。在Bash中异步运行命令时:

  

shell不等待命令完成,返回状态为0(true)。

但是,请注意,只有出现才能执行您想要的操作。您的其他命令(例如sleepseq)实际上仍在后台运行。您可以使用以下方式验证:

$ { echo 1 & sleep 10 & seq 10 & } | awk -e 'NR==1 {print $1; exit}'; pgrep sleep
1
14921

正如您所看到的,这允许awk处理echo的输出而无需等待完整的命令列表,但它并没有真正使命令列表的执行短路。流程替换仍然可能是正确的解决方案,但知道您有替代方案总是好的。