如何在bash中正确地读取流

时间:2015-06-25 11:55:49

标签: bash shell

我正在从共享内存中读取一个产生无限信息输出的流,例如:

0x1 (TimeStamp) 12Bytes:11216 +     1771/(47999+1) (0.036896) delta= 0+    1536/(47999+1) (0.032000) 11216.013361 23.534ms 2015.06.25 11:51:16.525
0x4 (ReferenceTime) 12Bytes:11215 + 24786286/(26999999+1) (0.918011) delta= 0+  806359/(26999999+1) (0.029856) 11216.013376 -95.366ms 2015.06.25 11:51:16.525
0x6 (ProcessDelay) 4Bytes: 32 (0x20)
0x7 (ClockAccuracy) 8Bytes: offset=0.000ppm (+-0.000ppm)
0xb (ClockId) 8Bytes: 01 00 00 00 42 22 01 00
0x20001 (SampleRate) 4Bytes: 48000 (0xbb80)
0x20002 (Channels) 4Bytes: 6 (0x6)
0x20003 (PcmLevel) 24Bytes: -11041 -11541 -49076 -86121 -24846 -24382
0x20004 (PcmPeak) 24Bytes: -8088 -8697 -37244 -84288 -21437 -21769
0x2000e (DolbyDpMetadata) 39352Bytes:
Linear Time: 11216 +     1771/(47999+1) (0.036896) delta= 0+    1536/(47999+1) (0.032000)

如果我尝试使用以下命令读取流:

while read line; 
do 
    echo "$line";
    echo "im here!"
done < <(../tools/spucat adec-68)

其中spucat是一个cpp二进制文件exacutable,它使用printf()有关传入数据包的信息在控制台上连续打印出来。

这是结果:

im here!
�k�G��E�x����b��h�������c����2��/n��-�U���QE�L�x���c�������������������������������x��4����O��M�����/��(������������������~��E�*�������;
im here!
������r��$�|��J�n�P�4�

如果我使用此命令启动脚本:

while read line; 
do 
    echo "$line";
    echo "im here!"
done < $(../tools/spucat adec-68)

它实际上永远不会进入while循环,只是开始打印出结束的流。 是否有一种方法可以逐行读取并在while循环中处理它?<​​/ p>

2 个答案:

答案 0 :(得分:1)

首先,第二个循环根本不起作用,因为您尝试将命令替换的结果(字符串)重定向到stdin。看看这个简单的例子:

_.tap

给出了:

while read line ; do echo "$line"; done < $(ls -l)

您需要使用流程替换:

bash: $(ls): ambiguous redirect

或所谓的 here string

< <(../tools/spucat adec-68)

另一件事。如果您读取任意二进制数据,我建议使用<<<$(../tools/spucat adec-68) 的{​​{1}}选项。这可以防止反斜杠被解释为转义字符。我不确定这是否是问题的完整解决方案,但应使用-r

答案 1 :(得分:1)

spucat正在转向标准错误(不明白为什么),所以要处理它必须重定向到标准输出:

while read -r line; 
do 
    echo "$line";
    echo "im here!"
done < <(../tools/spucat -p 4 adec-68  2>&1 > /dev/null)