Bash:从循环流中捕获stdError

Bash:从循环流中捕获stdError,bash,stdout,stderr,Bash,Stdout,Stderr,我有一个cpp可执行文件(mycat),它可以从共享内存中连续读取循环音频流,并将数据传输到stdOut,将元数据信息传输到stdErrmycat为音频流的每个条目输出12行,其中包含元数据信息,如下所示: 0x1 (TimeStamp) 12Bytes:2956 + 6793/(47999+1) (0.141521) delta= 0+ 1536/(47999+1) (0.032000) 2956.151418 -9.898ms 2016.04.04 16:06:37.700 0

我有一个cpp可执行文件(
mycat
),它可以从共享内存中连续读取循环音频流,并将数据传输到stdOut,将元数据信息传输到stdErr
mycat
为音频流的每个条目输出12行,其中包含元数据信息,如下所示:

0x1 (TimeStamp) 12Bytes:2956 +     6793/(47999+1) (0.141521) delta= 0+    1536/(47999+1) (0.032000) 2956.151418 -9.898ms 2016.04.04 16:06:37.700
0x4 (ReferenceTime) 12Bytes:2956 +  6156972/(26999999+1) (0.228036) delta= 0+ 1618519/(26999999+1) (0.059944) 2956.151426 76.610ms 2016.04.04 16:06:37.700
0x6 (ProcessDelay) 4Bytes: 64 (0x40)
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: -21307 -20348 -31737 -42427 -28786 -26525
0x20004 (PcmPeak) 24Bytes: -14366 -13360 -25203 -39427 -19067 -21307
0x2000e (DolbyDpMetadata) 39352Bytes:
Linear Time: 2956 +     6793/(47999+1) (0.141521) delta= 0+    1536/(47999+1) (0.032000)
2016.04.04 16:06:37.700 update: slot=0xe2840 validTo=0x3d1dd180 shmT=0x3d195200 (delta=294784) doffset=0xec2c0 msize=39552 dsize=18432 type=0x20001 (PCMS16) data bytes: df f4 f2 fc
我想要的是一个bash脚本:

1) 启动
mycat
例如
/mycat shm\u name>/dev/null

2) 从
mycat
读取stdErr,直到第12行,无论从何处开始

2.1)最终将12行存储到变量中(这是可选的)

3) 在第12行之后立即杀死
mycat
,这样bash脚本就可以继续,而不会被即将出现的stdError惹恼

4) 读取行“Channels”(在本例中为6)的值,并将其存储到名为“Channels”的变量中

5) 读取行“SampleRate”(在本例中为48000)的值,并将其存储在名为“rate”的变量中


有办法吗?

您可以使用
mycat shm\u name>/dev/null 2>/path/to/file
重定向stderr。到时候,你可以用
killall mycat
杀死mycat。要存储变量,需要导出通道=,模式与速率相同。您可以找到那些具有
grep
的。不过,我不知道如何精确地等待12行。

首先,您需要将STDERR重定向到STDOUT,并使STDOUT变为null

mycat 2>&1 >/dev/null | parsing_script
然后需要一个解析脚本来收集数据

 #!/bin/bash

declare -a data=()
count=1
while read line; do
   data+=( "$line
   ")
   ((count++))

   string=$(echo $line|sed 's/.*(\(.[A-Za-z]*\)).*/\1/')
   case $string in
      SampleRate) rate=$(echo $line|sed 's/.*: \(.[0-9]*\) .*/\1/')
        ;;
      Channels) channels=$(echo $line|sed 's/.*: \(.[0-9]*\) .*/\1/')
        ;;
      *) true;;
   esac
   if [[ $count -gt 12 ]]; then
      break
   fi
done <&0

echo $channels
echo $rate
#/bin/bash
声明-a数据=()
计数=1
读行时;做
数据+=(“$line
")
((count++)
字符串=$(echo$行| sed's/*(\([A-Za-z]*\)./\1/'))
案例$string in
SampleRate)rate=$(echo$行| sed's/*:\([0-9]*\)./\1/)
;;
通道)通道=$(echo$行| sed's/*:\([0-9]*\)./\1/)
;;
*)是的;;
以撒
如果[$count-gt 12]];然后
打破
fi

完成我找到了一个优雅的解决方案:

while read -r line;                                         # Read mycat line by line
do
    if echo "$line" | grep -qi "SampleRate"; then           # Search for line containing string 'SampleRate'
        rate="${line#*:}";                                  # Remove all charachters till ':' 
        rate="${rate%(*}";                                  # Remove all charachters from '('
        rate="$(echo -e "${rate}" | tr -d '[[:space:]]')"   # Remove all tralling withespace
    elif echo "$line" | grep -qi "Channels"; then
        channels="${line#*:}";
        channels="${channels%(*}";
        channels="$(echo -e "${channels}" | tr -d '[[:space:]]')"
    fi

    if [ -n "$channels"  ] && [ -n "$rate"  ]; then         # If both variables 'channels' and 'rate' are not empty kill the while loop
        break;
    fi
done < <(./mycat $shm_name  2>&1 > /dev/null)           # Mycat is processed into a while loop, standard Error is redirected to standard Output ( 2>&1 )

echo "Found datarate: $rate"
echo "Found channels: $channels"
读取时-r行;#逐行阅读mycat
做
如果echo“$line”| grep-qi“SampleRate”;然后#搜索包含字符串“SampleRate”的行
rate=“${line#*:}”;#删除所有字符,直到“:”
rate=“${rate%(*}”;#从“(”中删除所有字符
rate=“$(echo-e“${rate}”| tr-d'[:space:][]”)#用espace删除所有tralling
elif echo“$line”| grep-qi“频道”;然后
channels=“${line#*:}”;
channels=“${channels%(*}”;
channels=“$(echo-e“${channels}”| tr-d'[:space:][]”)
fi
如果[-n“$channels”]&&&&n“$rate”];那么#如果变量“channels”和“rate”都不是空的,则终止while循环
打破
fi
完成<&1>/dev/null)#Mycat被处理成一个while循环,标准错误被重定向到标准输出(2>&1)
echo“找到的数据速率:$rate”
echo“找到的频道:$channels”