pactl list sink-inputs
和pacmd list-sink-inputs
的输出都包含“属性”部分:
Properties:
media.name = "ALSA Playback"
application.name = "ALSA plug-in [snapclient]"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "29"
application.process.id = "6393"
application.process.user = "root"
application.process.host = "xxxxxx"
application.process.binary = "snapclient"
application.language = "C"
application.process.machine_id = "8dadf95c2f504864bc0f8b3ab149cbe0"
application.process.session_id = "c4"
module-stream-restore.id = "sink-input-by-application-name:ALSA plug-in [snapclient]"
我想知道是否有办法通过application.process.id
或application.process.binary
直接查找接收器输入的索引,而不需要解析上述命令的多行输出或者写一个单独的C程序。
答案 0 :(得分:1)
某些命令也接受唯一名称而不是id,但是您尝试使用的名称似乎无法执行此操作。可能是因为名称不是唯一的,并且可能存在多个匹配项。你需要自己解析它。这就是我想出的:
pacmd list-sink-inputs |
tr '\n' '\r' |
perl -pe 's/ *index: ([0-9]+).+?application\.name = "([^\r]+)"\r.+?(?=index:|$)/\2:\1\r/g' |
tr '\r' '\n'
perl -pe
就像sed
一样,更好。这基本上匹配index: [id] [anything] application.name = [name] [anything]
并将输出格式化为类似
3 sink input(s) available.
"speech-dispatcher":166
"SoX":407
"Clementine":413
然后你可以grep或sed。
答案 1 :(得分:0)
虽然它确实解析了输出并且还没有为你可能正在寻找的id做任何匹配,但是这个方法将提供一种方法,通过一些修改,通过sink id获取该信息:
pactl list sink-inputs | while read -r line ; do
#echo "Processing ${line}"
echo $line | grep -oP 'Sink Input #\K[^$]'
echo $line | grep -oP 'application.process.id = "\K[^"]+'
echo $line | grep -oP 'application.process.binary = "\K[^"]+'
done
答案 2 :(得分:0)
很长、易于理解、可维护的方法(使用application.process.binary)
结果
ffmpeg | 3
firefox-esr | 24
firefox-esr | 58
vlc | 43
Bash 脚本
str="$(pacmd list-sink-inputs)"
list1=$(printf '%s' "$str" | grep 'index: ')
list2=$(printf '%s' "$str" | grep 'application.process.binary = "')
arr1=()
arr2=()
while read line; do
arr1+=("${line:7}")
done <<< "$list1"
while read line; do
arr2+=("${line:30:-1}")
done <<< "$list2"
for index in ${!arr1[@]}; do
s1="${arr1[index]}"
s2="${arr2[index]}"
echo "$s2 | $s1"
done
另一种方法(有点晦涩)
str="$(pacmd list-sink-inputs)"
arr1=($(printf '%s' "$str" | grep 'index: ' | rev | cut -d' ' -f 1 | rev))
arr2=($(printf '%s' "$str" | grep 'application.process.binary' | cut -d'"' -f 2))
for index in ${!arr1[@]}; do
s1="${arr1[index]}"
s2="${arr2[index]}"
echo "$s2 | $s1"
done
最后,我找到了最短的解决方案:
str="$(pacmd list-sink-inputs)"
paste -d\| \
<(printf '%s' "$str" | grep 'application.process.binary' | cut -d'"' -f 2) \
<(printf '%s' "$str" | grep 'index: ' | rev | cut -d' ' -f 1 | rev)