我想在提供结果后立即退出,不要等待其余的工作。我通过不同的方法提供了三个例子,即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
答案 0 :(得分:0)
我希望在以下示例中显示“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)。
但是,请注意,只有出现才能执行您想要的操作。您的其他命令(例如sleep
和seq
)实际上仍在后台运行。您可以使用以下方式验证:
$ { echo 1 & sleep 10 & seq 10 & } | awk -e 'NR==1 {print $1; exit}'; pgrep sleep
1
14921
正如您所看到的,这允许awk处理echo
的输出而无需等待完整的命令列表,但它并没有真正使命令列表的执行短路。流程替换仍然可能是正确的解决方案,但知道您有替代方案总是好的。