我希望在创建shell时处理shell的每个stdout-line。我想获取test.sh
的输出(一个很长的过程)。我目前的做法是:
./test.sh >tmp.txt &
PID=$!
tail -f tmp.txt | while read line; do
echo $line
ps ${PID} > /dev/null
if [ $? -ne 0 ]; then
echo "exiting.."
fi
done;
但不幸的是,这将打印“退出”然后等待,因为尾部-f仍在运行。我尝试了break
和exit
我在FreeBSD上运行它,所以我不能使用某些linux尾部的--pid=
选项。
我可以使用ps
和grep
获取尾部的pid并将其杀死,但这对我来说似乎非常难看。
任何提示?
答案 0 :(得分:2)
为什么需要tail
流程?
你能不能按照
的方式做点什么./test.sh | while read line; do
# process $line
done
或者,如果你想保持输出在tmp.txt:
./test.sh | tee tmp.txt | while read line; do
# process $line
done
如果您仍想使用中间tail -f
进程,也许您可以使用命名管道(fifo)而不是常规管道,以允许分离tail
进程并获取其pid:< / p>
./test.sh >tmp.txt &
PID=$!
mkfifo tmp.fifo
tail -f tmp.txt >tmp.fifo &
PID_OF_TAIL=$!
while read line; do
# process $line
kill -0 ${PID} >/dev/null || kill ${PID_OF_TAIL}
done <tmp.fifo
rm tmp.fifo
然而,我应该提到这样的解决方案存在几个严重的竞争条件问题:
test.sh
的PID可以被其他进程重用; test.sh
进程在您读完最后一行时仍处于活动状态,则之后您将无法再检测到其死亡,并且您的循环将会挂起。