我有一个简单的应用程序,它从传感器捕获数据并将其打印为输出“Received datavalue”,现在我需要解析所有行并对数据执行某些操作。我找到了简单的bash脚本:
set -o pipefail
(./myapp) |
(
while read; do
if [ `echo $REPLY | grep -c "Received"` -eq 1 ]; then
echo Found error: $REPLY >/dev/stderr
exit 2
fi;
echo $REPLY
done
)
exit $?
但它不起作用。我在bash调试模式下运行此脚本,并在运行myapp后挂起。应用程序“myapp”正在循环运行,永远不会结束。
问候。
编辑:修复脚本语法
我不知道怎么做所以我问google并找到了解决我问题的脚本。原始剧本:
set -o pipefail
(echo "foo"; echo "error"; echo "baz") |
(
while read; do
if [ `echo $REPLY | grep -c "error"` -eq 1 ]; then
echo Found error: $REPLY >/dev/stderr
exit 2
fi;
echo $REPLY
done
)
exit $?
它按我的需要工作,但它解析了命令输出。我有这样的输出应用程序:
notroot@ro:$ ./myapp
Received 31250
Received 31250
Received 31250
Received 31250
Received 31250
Received 31250
Received 31187
Received 31187
申请永无止境。运行应用程序时脚本挂起
抱歉,我无法更准确地解释它。
编辑2:
我发现使用strace的问题 - 脚本进程正在等待结束子进程(myapp),但它永远不会结束。所以现在的问题是:bash能否“在飞行中”从app输出中获取行?
答案 0 :(得分:2)
您似乎已经向后获得了脚本的结构。通常,bash本身不适合从另一个程序的输出逐行解析。例如,
$ ping google.com
给出了表格的永无止境的输出:
PING google.com (74.125.228.206) 56(84) bytes of data.
64 bytes … (74.125.228.206): icmp_seq=1 ttl=57 time=17.6 ms
64 bytes … (74.125.228.206): icmp_seq=2 ttl=57 time=19.6 ms
64 bytes … (74.125.228.206): icmp_seq=3 ttl=57 time=14.9 ms
…
每秒发出一行。如果将其输出传递给功能更强大的解析器,如:
$ ping google.com | awk '
/icmp_seq=5/ { print "error", $8; exit }
/time=/ { print "ok", $6}'
你会得到类似的东西:
ok time=16.5
ok time=12.5
ok time=13.0
ok time=16.6
error icmp_seq=5
这比你尝试使用bash read
循环要简单得多。使用正确的工具来完成工作确实有帮助。有一个非常简单的introduction to awk at Wikibooks。