在bash中捕获多个并行grep输出

时间:2014-08-22 22:52:41

标签: linux bash scripting

我的窘境在于将grep结果汇总到变量以供以后使用。通常情况下,这不是一个问题,我会使用$( )并按原样将结果推送到变量。

当我需要使用&运算符并行运行多个ping实例时,会出现此问题。代码段:

google_ping=$(ping -c 2 www.google.com | grep -oP '\d+(?=% packet loss)') &
bing_ping=$(ping -c 2 www.bing.com | grep -oP '\d+(?=% packet loss)') &
custom_ping=$(ping -c 2 10.1.1.1 | grep -oP '\d+(?=% packet loss)') &

wait

printf "Google Ping: \t\e[32m %3d\e[0m\n " $google_ping
printf "Bing Ping:\t\e[32m %3d\e[0m\n " $bing_ping
printf "Custom Ping:\t\e[32m %3d\e[0m\n " $custom_ping

我有更多的ping运行,并且这已经缩短,以使代码比现在更少混乱。基本上,每次ping每个目标两次,检索每个目标的丢包,并同时发布所有结果,而不是在它们可用时发布。

我得到的结果似乎是错误输出(已经是0)而不是数据包丢失。对于custom_ping,这是一个受控测试(总是返回100%丢包),结果仍为0,而不是这些greps应该检索的100个。

运行与printf一致的命令,如下所示:

printf "Google Ping: \t\e[32m %3d\e[0m\n " $(ping -c 2 www.google.com | grep -oP '\d+(?=% packet loss)') &
#etc...

偶尔会工作,但通常会通过将ping结果放在彼此旁边或彼此之内来扭曲输出,等等。更不用说我需要稍后使用结果的值来根据有多高执行某些操作或者数据包丢失很少,我最终还需要拉出数据包所用的毫秒数。

我尝试过并行运行ping的不同方法;包括使用反引号代替$( )并通过2>$1重定向输出。我想尽量避免使用临时文件,如果有的话。

还有其他方法更有效吗?或者也许是将一个站点的所有ping结果放入变量并使用类似于grep的命令或函数来提取我需要的信息的方法?

作为参考,整个脚本位于pastebin here

1 个答案:

答案 0 :(得分:0)

如果不使用临时文件之类的东西,根本无法做你想做的事情。 (或类似于memcached或redis的类似半持久存储。)幸运的是,所有这些解决方案都相当快。您的/tmp目录很可能实际上是一个ramdisk,如果没有,您可以制作一个或使用其中一个内存缓存解决方案。

您正在使用的命令:

var=$(pipeline) &

导致var=$(pipeline)在后​​台子shell中运行。在该shell中,管道将被执行,其输出由子shell $var捕获。但这并没有用,因为子shell即将终止,用它来获取变量。

您可以将&放在$(...)内,在这种情况下,该值将分配给外壳中的$var。但$(pipeline&)命令替换waitpipeline pipeline,这很好地违背了在后台运行{{1}}的目的。