从 `pactl` 输出中提取字符串并作为变量传递给 shell 脚本

从 `pactl` 输出中提取字符串并作为变量传递给 shell 脚本

我正在尝试编写一个脚本,允许我从 shell 更改蓝牙扬声器音量。我可以对接收器的值进行硬编码,它工作得很好:

#!/usr/bin/env bash
for level in "$@"
do 
pactl set-sink-input-volume 267 $level
done

我通过运行获得“267”值:

pactl list sink-inputs

其提供如下输出:

Sink Input #267
    Driver: protocol-native.c
    Owner Module: 10
    Client: 151
    Sink: 7
    Sample Specification: float32le 2ch 44100Hz
    Channel Map: front-left,front-right

我关心的只是 Sink Input # 之后输出的第一行中的三位数值

就像我说的,如果我在脚本中对 267 值进行硬编码,一切都会正常工作,直到我重新启动蓝牙扬声器,然后该值才会发生变化。

有没有办法我可以通过脚本提取该值并将其作为变量传递给pactl set-sink-input-volume 267 $level脚本的位?

答案1

有两种方法可以实现这一点。这一切都假设您想在参数中将一个数字传递给脚本,并将第一个接收器的体积更改为参数。

您最初建议的方式(echo验证其有效后删除):

#!/bin/bash

pactl list sink-inputs | grep -hPo '^Sink Input #\K\d+$' | head -n 1 | xargs -n 1 -I{} echo pactl set-sink-input-volume "{}" "$1"

echo一旦您确认要执行的命令正确,就删除。

或者,@steeldriver 在问题的评论中指出,有一种short更快、更容易解析的形式(再次删除echo):

#!/bin/bash

pactl list short sink-inputs | head -n 1 | awk '{print$1}' | xargs -n 1 -I{} echo pactl set-sink-input-volume "{}" "$1"

答案2

可能有更好的方法来获取您想要的精确脉冲音频 ID,但是,既然您询问如何在 bash 脚本中解析它,那就开始吧!

您的请求是运行另一个 bash 命令并捕获输出,如下所示:

sinkid=$(pactl list sink-inputs | egrep "Sink Input #" | egrep -o [0-9]+)

分解成几个部分:

  • sinkid是我们创建的变量(请注意,Bash 是一种不允许x=y变量赋值之间有空格的语言)
  • =告诉 bash 我们正在将它的值分配给某个东西
  • $( ... )表示我们正在运行命令。您可能会看到其他人使用重音符/反引号,但有些人(包括我自己)认为这更清楚。
  • pactl list sink-inputs是您正在运行的现有命令。
  • |说我们正在将其输出“传输”到另一个命令中
  • grep "Sink Input #"找到我们感兴趣的行
  • |再次通过管道传输输出,以便我们可以使用另一个 grep 命令进一步处理它。
  • egrep -o [0-9]+"Sink Input #123仅从输出行中查找数字123

现在您可以用如下命令替换原始命令sinkid

pactl set-sink-input-volume "$sinkid" "$level"

相关内容