我想要一个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"
该脚本会终止,但是脚本本身在写入输出的后台进程之前完成,所以首先显示提示符, 然后显示输出,让终端看起来像脚本仍在运行的空白行。 你可以输入任何命令而不是返回,并执行该命令。
为了避免这种情况,您需要在退出脚本之前在显式后台作业中运行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
读取输入。 一旦运行,您可以将所有输出重定向到管道并启动“主”脚本。 退出陷阱确保您的脚本实际上不会退出,直到while
循环完成; 它也为您清理命名管道。
您可能还没有注意到,但不能保证while
循环将按照写入它们的确切顺序接收合并的标准输出和标准错误。 例如,
echo out1 echo err1 >&2 echo out2 echo err2 >&2
可能最终被认为是
out1 err1 err2 out2
每个流本身将保持秩序,但可以任意合并。