![从 `pactl` 输出中提取字符串并作为变量传递给 shell 脚本](https://linux22.com/image/905092/%E4%BB%8E%20%60pactl%60%20%E8%BE%93%E5%87%BA%E4%B8%AD%E6%8F%90%E5%8F%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%B9%B6%E4%BD%9C%E4%B8%BA%E5%8F%98%E9%87%8F%E4%BC%A0%E9%80%92%E7%BB%99%20shell%20%E8%84%9A%E6%9C%AC.png)
我正在尝试编写一个脚本,允许我从 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"