Bash - 如何解析正在运行的应用程序的输出

时间:2014-07-19 19:16:25

标签: bash shell parsing

我有一个简单的应用程序,它从传感器捕获数据并将其打印为输出“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输出中获取行?

1 个答案:

答案 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