首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash:从环流捕获stdError

问Bash:从环流捕获stdError
EN

Stack Overflow用户
提问于 2016-04-04 16:39:15
回答 3查看 28关注 0票数 0

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

代码语言:javascript
复制
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 eg../mycat shm_name > /dev/null。

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

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

3)在第12行之后立即杀死mycat,这样bash脚本就可以继续运行,而不会被输出的stdError所困扰。

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

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

有办法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-06 08:50:46

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

代码语言:javascript
复制
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"
票数 0
EN

Stack Overflow用户

发布于 2016-04-04 17:05:15

您可以使用mycat shm_name > /dev/null 2>/path/to/file重定向stderr。当时机成熟时,你可以用killall mycat杀死我的猫。对于存储变量,您需要export channels =,与速率相同的模式。你可以用grep找到那些。不过,我不知道怎么等十二行。

票数 0
EN

Stack Overflow用户

发布于 2016-04-04 17:34:16

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

代码语言:javascript
复制
mycat 2>&1 >/dev/null | parsing_script

然后,您需要一个解析脚本来收集数据。

代码语言:javascript
复制
 #!/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

我回显了这些值,但是您可以将它们重定向到一个文件,格式化它们,等等。而且,${data@}包含您的元数据。因为你是管道,我正在读STDIN,但如果你想调整它,它可能会更健壮。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36408224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档