将命令过滤输出读入Bash数组时出现空数组的问题
问题
尝试将gst-device-monitor-1.0命令的过滤输出读入Bash数组时,结果为空数组;但不加过滤直接读取命令输出时,数组能正常填充。
命令常规输出
gst-device-monitor-1.0 -f Source/Network:application/x-ndi Probing devices... Monitoring devices, waiting for devices to be removed or new devices to be added... Device found: name : PRO-CONVERT HDMI-NDI 001 (#00 (A405200518097)) class : Source/Audio/Video/Network caps : application/x-ndi properties: ndi-name = "PRO-CONVERT\ HDMI-NDI\ 001\ \(\#00\ \(A405200518097\)\)" url-address = 198.18.1.98:5961 gst-launch-1.0 ndisrc ndi-name="PRO-CONVERT\ HDMI-NDI\ 001\ \(\#00\ \(A405200518097\)\)" url-address=198.18.1.98:5961 ! ... Device found: name : UBUNTU (2110_Transcoder_01) class : Source/Audio/Video/Network caps : application/x-ndi properties: ndi-name = "UBUNTU\ \(2110_Transcoder_01\)" url-address = 198.18.1.94:5961 gst-launch-1.0 ndisrc ndi-name="UBUNTU\ \(2110_Transcoder_01\)" url-address=198.18.1.94:5961 ! ... Device found: name : PRO-CONVERT HDMI-NDI 002 (#00 (A405200518100)) class : Source/Audio/Video/Network caps : application/x-ndi properties: ndi-name = "PRO-CONVERT\ HDMI-NDI\ 002\ \(\#00\ \(A405200518100\)\)" url-address = 198.18.1.53:5961 gst-launch-1.0 ndisrc ndi-name="PRO-CONVERT\ HDMI-NDI\ 002\ \(\#00\ \(A405200518100\)\)" url-address=198.18.1.53:5961 ! ...
过滤命令及输出
使用以下命令过滤出设备名称:
gst-device-monitor-1.0 -f Source/Network:application/x-ndi | awk '/name :/ {$1=$2=""; print$0}'
得到的输出为:
PRO-CONVERT HDMI-NDI 001 (#00 (A405200518097)) PRO-CONVERT HDMI-NDI 002 (#00 (A405200518100)) UBUNTU (2110_Transcoder_01)
读入数组失败的命令
尝试用以下命令将过滤输出读入数组:
readarray -t sources < <(gst-device-monitor-1.0 -f Source/Network:application/x-ndi | awk '/name :/ {$1=$2=""; print$0}')
执行后用declare -p sources或echo ${sources[@]}查看数组,结果为空,但不加过滤直接读取命令输出到数组则能正常获取所有值。
原因与解决方法
核心原因
gst-device-monitor-1.0默认会持续运行(进入监听模式,等待设备新增/移除),不会自动退出。当你用管道连接awk时,虽然awk能实时输出匹配到的行,但readarray会一直等待输入流结束,而原命令不退出的话,输入流永远不会关闭,导致readarray一直处于等待状态,此时查看数组自然是空的。
而不加过滤直接读取时,你可能是在命令输出完设备列表后手动终止了进程,此时输入流关闭,readarray才会完成读取填充数组。
解决方法
有两种可行的处理方式:
让
gst-device-monitor-1.0输出设备列表后自动退出
使用--once参数,命令会在探测完当前设备后立即退出,不再进入监听模式:readarray -t sources < <(gst-device-monitor-1.0 --once -f Source/Network:application/x-ndi | awk '/name :/ {$1=$2=""; print $0}')限制命令运行时间,强制终止输入流
如果无法使用--once参数(比如旧版本GStreamer不支持),可以用timeout命令限制命令运行时长,确保输入流能关闭:readarray -t sources < <(timeout 3s gst-device-monitor-1.0 -f Source/Network:application/x-ndi | awk '/name :/ {$1=$2=""; print $0}')这里设置3秒足够让命令完成设备探测,可根据实际情况调整时长。
内容的提问来源于stack exchange,提问作者CyberNBD
相关产品推荐
相关产品推荐

