Bash: 从循环流中捕获 stdError
Bash: capture stdError from looped stream
我有一个 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_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_name > /dev/null 2>/path/to/file
重定向 stderr。时机成熟时,您可以使用 killall mycat
杀死 mycat。为了存储变量,您需要 export channels =
,与速率相同的模式。您可以找到带有 grep
的那些。不过,我不确定如何准确地等待十二行。
首先,您需要将 STDERR 重定向到 STDOUT,并让 STDOUT 变为空。
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]*\)).*//')
case $string in
SampleRate) rate=$(echo $line|sed 's/.*: \(.[0-9]*\) .*//')
;;
Channels) channels=$(echo $line|sed 's/.*: \(.[0-9]*\) .*//')
;;
*) true;;
esac
if [[ $count -gt 12 ]]; then
break
fi
done <&0
echo $channels
echo $rate
我回显了这些值,但您可以将它们重定向到文件、格式化它们等。另外,${data[@]} 包含您的元数据。因为你在管道,我正在从 STDIN 读取,但如果你想调整它可能会更健壮。
我找到了一个优雅的解决方案:
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"
我有一个 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_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_name > /dev/null 2>/path/to/file
重定向 stderr。时机成熟时,您可以使用 killall mycat
杀死 mycat。为了存储变量,您需要 export channels =
,与速率相同的模式。您可以找到带有 grep
的那些。不过,我不确定如何准确地等待十二行。
首先,您需要将 STDERR 重定向到 STDOUT,并让 STDOUT 变为空。
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]*\)).*//')
case $string in
SampleRate) rate=$(echo $line|sed 's/.*: \(.[0-9]*\) .*//')
;;
Channels) channels=$(echo $line|sed 's/.*: \(.[0-9]*\) .*//')
;;
*) true;;
esac
if [[ $count -gt 12 ]]; then
break
fi
done <&0
echo $channels
echo $rate
我回显了这些值,但您可以将它们重定向到文件、格式化它们等。另外,${data[@]} 包含您的元数据。因为你在管道,我正在从 STDIN 读取,但如果你想调整它可能会更健壮。
我找到了一个优雅的解决方案:
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"