在自身内部过滤shell脚本输出时,脚本不会终止

时间:2016-11-12 15:47:00

标签: linux bash shell

我想要一个Bash脚本来生成一些输出消息。该脚本应该捕获消息,进行一些过滤,转换,然后将它们输出到屏幕。

过滤后的结果在输出中是正确的,但脚本不会终止。我必须按一个返回键才能完成它。我该如何解决?

演示脚本:

#!/bin/bash

exec &> >( 
        {
        while read line; do
            [ "$line" = "exit" ] && break 
            echo "`date +%H:%M:%S.%N` $line" 
        done
        echo "while finish"
        } )

for ((i=3;i--;)); do
    echo "text $i"
done

echo "exit"

1 个答案:

答案 0 :(得分:1)

脚本 终止,但脚本本身在写入输出的后台进程完成之前完成,因此首先显示提示,然后输出,离开你的带有空白行的终端看起来,就像脚本仍在运行一样。您可以键入任何命令而不是命中return,该命令将执行。

为避免这种情况,您需要在显式后台作业中运行while循环,您可以在退出脚本之前等待。

mkfifo logpipe
trap 'wait $logger_pid; rm logpipe' EXIT

while read line; do
    [ "$line" = "exit" ] && break
    echo "$(date +%H:%M:%S.%N) $line"
done < logpipe &
logger_pid=$!

exec &> logpipe

# ==========

for ((i=3;i--;)); do
    echo "text $i"
done

echo "exit"

while循环在后台运行,从命名管道logpipe读取其输入。一旦运行,您可以将所有输出重定向到管道并启动&#34; main&#34;脚本。退出陷阱确保您的脚本在while循环完成之前不会实际退出;它还会为您清理命名管道。

您可能还没有注意到,但无法保证while循环将按照写入内容的确切顺序接收合并的标准输出和标准错误。例如,

echo out1
echo err1 >&2
echo out2
echo err2 >&2

可能最终被视为

out1
err1
err2
out2

每个流本身将保持有序,但两者可以任意合并。