通知/ proc下文件的更改


13

我用bash编写了一个小的“守护程序”,如果检测到耳机,它将切换到耳机,否则,将切换到带有PulseAudio的外部USB扬声器。

我正在寻找的是一种获取文件更改通知的方法/proc/asound/card0/codec#0,就像inotifywait在真实文件上一样(将/ proc下的文件视为“伪文件”)。

我发现我的代码有点疯狂,因为它整天都可以运行sleep 1awk每天运行86400次:)

while sleep 1; do
    _1=${_2:-}
    _2=$(awk '/Pin-ctls/{n++;if(n==4)print}' '/proc/asound/card0/codec#0')

    [[ ${_1:-} = $_2 ]] ||
        if [[ $_2 =~ OUT ]]; then
            use_speakers
        else
            use_internal
        fi
done

我正在寻找的是类似的东西(此示例不起作用):

codec=/proc/asound/card0/codec#0
while inotifywait $codec; do
    if [[ $(awk '/Pin-ctls/{n++;if(n==4)print}' $codec) =~ OUT ]]; then
        use_speakers
    else
        use_internal
    fi
done

这样,仅当$codec文件上有实际更改时,才会运行循环内的命令。


1
这不是疯狂的-诸如topGUI系统监视器之类的东西比从/proc短时间间隔读取的东西要多得多。当然,它们作为已编译的可执行文件的执行效率可能更高,但要点是:轮询信息是一项常见的任务。
goldilocks 2013年

2
由于根本的问题不是您所独有的,所以我希望有一些现成的解决方案(至少对于某些硬件而言)-请查看unix.stackexchange.com/questions/25776/…superuser.com/questions / 339900 /…。最终的来源当然是内核树(以及硬件规范,如果您决定将其实施到某些驱动程序中)。
peterph 2013年

1
如果这在中显示/proc,您可能可以使用udev规则触发脚本,这将是非常理想的。不太理想的是使用udev规则会
带来多大的麻烦

@peterph据我所知,hda-verb提供了一个用于设置或检查参数的界面,但看起来我也必须每秒运行一次。
Teresa e Junior

@goldilocks插入耳机不会发送任何udev事件。还是我想念的更多东西?
Teresa e Junior

Answers:


10

我正在寻找某种方法来获取文件更改的通知[proc]

您不能,因为它们不是文件。这不是一个重复的问题,但是这里的答案解释了原因。

/proc是内核接口。那里没有真实的文件,因此它们不能更改。从句柄读取是一个请求,读取文件中的数据是对此的答复。

您可以模拟这样的事情的唯一方法是定期读取文件并比较内容,以查看内核的回复是否已更改-好像您已经做到了。

如果您处理stat文件,则atime和mtime将相同:对于某些文件,无论何时stat调用都在此,对于其他文件,则是系统引导期间的时间。在第一种情况下,它似乎总是改变了,在第二种情况下,它似乎从未改变过。


不幸的是,即使每秒轮询一次,也会增加可观的延迟(例如500毫秒)。我希望可以有一种更快/更有效的方法,但是既然您提到过top之类的应用程序都以相同的方式进行操作,我想我会保持这种状态。
Teresa e Junior

@TeresaeJunior如果延迟是一个问题(我认为不在这里),例如,因为在计算中使用了轮询的持续时间,那么您将对实际持续时间进行计时(而不仅是使用要求您入睡的时间) 。不过,这似乎很多。我从来没有分析过bash脚本,所以我不知道在这里什么是正常的(嗯……很好的独立问题)。调用awk ==之类的fork()东西很昂贵;如上所述,全部用C编写的实用程序将具有更快的方法。我仍然认为您不会给整个系统增加太多负载。
goldilocks 2013年

1
不,对不起,我的意思是:从我插入耳机到下次入睡,会有一些明显的延迟。但是我不打算减少睡眠时间。谢谢你的帮助!
Teresa e Junior

4

如果您使用的是PulseAudio,请pactl subscribe执行此操作。


确实是的!几个月前,由于一些音频问题,我在编译PA 4.0之后开始使用它。Debian Stable上的版本是2.0(尽管他们最近已将4.0上传到backport),而subscribe2.0上没有。
Teresa e Junior

2

还请记住,/proc/允许通过轮询来监视某些文件的更改,例如,如果您这样做man proc,则可以阅读以下有关/proc/self/mounts文件的信息:

/ proc / [pid] / mounts(自Linux 2.4.19开始)此文件列出了当前在进程的安装名称空间中安装的所有文件系统(请参见mount_namespaces(7))。该文件的格式记录在fstab(5)中。

从内核版本2.6.15开始,此文件是可轮询的:打开文件进行读取后,此文件中的更改(即文件系统安装或卸载)导致select(2)将文件描述符标记为具有异常情况,并且poll(2)和epoll_wait(2)将文件标记为具有优先级事件(POLLPRI)。(在Linux 2.6.30之前,此文件中的更改通过将文件描述符标记为select(2)可读,并标记为poll(2)和epoll_wait(2)具有错误条件来指示。)

这正是以下问题中正在实现的内容:

/programming/5070801/monitoring-mount-point-changes-via-proc-mounts


-1

尝试使用netlink监视/proc文件更改。

https://mdlayher.com/blog/linux-netlink-and-go-part-1-netlink/


欢迎来到该网站。请添加一些有关如何使用netlink该任务的说明;从您链接的外部内容中看不出来。另外,通常最好不要使用“仅链接”的答案,因为外部内容可能会更改或删除(例如,请参阅原始链接页面顶部的注意事项),这会削弱您的贡献的用途。
AdminBee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.