当前,Debian中的/usr/sbin/alsa知道使用声卡的进程的方式如下:

echo $( \
    lsof +D /dev -F rt \
    | awk '/^p/ {pid=$1} /^t/ {type=$1} /^r0x(74|e)..$/ && type == "tCHR" {print pid}' \
    | cut -c 2- \
    | uniq \
)

这相当丑陋,并取决于lsof。我正在寻找不使用lsof的POSIX解决方案,也许使用/proc。
    time for i in /proc/*/fd/*; do readlink $i | grep -q /dev/snd/pcm && echo $i | awk -F '/' '{print $3}'; done | uniq

不幸的是,花费的时间似乎是上述基于lsof的代码段的两倍。为了使其成为可行的替代品,您可以使其更快吗?

更新我将以上内容重写为:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
        if readlink $i | grep -q /dev/snd/pcm
        then
                IFS=/; set -- $i; unset IFS; echo $3
        fi
done

但这似乎与我之前的代码片段具有相同的性能。我怀疑grep是罪魁祸首。

更新:我已经打开了关于该主题的Debian bug

最佳答案

您在这里开始了很多过程。相反,您可以尝试以与发布的lsof脚本类似的方式进行操作...,但是用shell for loop替换lsof:

如果要避免启动许多grep进程,请仅启动一个:

#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
    echo ${i%/fd/*} $(readlink $i)
done | grep -q /dev/snd/pcm

现在在我的桌面上需要4.5s,而每个打开的文件只有一个grep进程时是7.5s。

但是...我认为您的grep在这里不是必需的。如果您非常在意,可以尝试:
#!/bin/sh
for i in /proc/[0-9]*/fd/*
do
    var="$(readlink $i)"
    if test x"$var" != x"${var#/dev/snd/pcm}"
    then
        echo $i
    fi
done

对我来说,这甚至更快(test几乎始终是内置的shell),但是我想这更多是因为测试方法不好。尝试一下。

10-08 13:39