通知 /proc 下文件的更改

通知 /proc 下文件的更改

我在 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

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

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

/proc是一个内核接口。那里没有真正的文件,因此它们无法更改。从句柄读取是要求当你阅读文件时,文件中的数据就是对此的答复。

模拟类似情况的唯一方法是定期读取文件并比较内容以查看内核的回复是否已更改 - 看起来您已经这样做了。

如果您stat使用 procfs 文件,atime 和 mtime 将是相同的:对于某些文件,它是 stat 调用的时间,对于其他文件,则是系统启动期间的时间。在第一种情况下,它似乎总是发生了变化,在第二种情况下,它似乎永远不会改变。

答案2

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

答案3

另请记住,/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) 标记为具有错误情况。)

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

https://stackoverflow.com/questions/5070801/monitoring-mount-point-changes-via-proc-mounts

答案4

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

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

相关内容