/ procの下のファイルの変更を通知する


13

ヘッドフォンが検出されるとヘッドフォンに切り替わり、検出されない場合はPulseAudioを備えた外部USBスピーカーに切り替える小さな「デーモン」をbashで作成しました。

私が探して/proc/asound/card0/codec#0いるのinotifywaitは、実際のファイルと同じように、ファイルの変更の通知を取得する方法です(/ procの下のファイルを「疑似ファイル」と見なす)。

私は私のコードが少し狂っています、なぜならそれは一日中実行sleep 1awkれます、それは1日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
それは異常ではありません-GUI topシステムモニターのようなものは/proc、短い間隔でそれよりもずっと多くを読みます。もちろん、コンパイルされた実行可能ファイルとして、おそらくはるかに効率的に実行しますが、ポイントは次のとおりです。情報のポーリングは一般的なタスクです。
goldilocks

2
根底にある問題はあなただけのものではないので、(少なくとも一部のハードウェアについては)既成のソリューションがある期待ます-unix.stackexchange.com/questions/25776/…superuser.com/questionsを見てください/ 339900 / ...。究極のソースは、もちろんカーネルツリーです(そして、それを何らかのドライバーに実装することに決めた場合のハードウェア仕様)。
ペテルフ

1
これがに表示される/proc場合は、おそらくudevルールを使用してスクリプトをトリガーできます。これは非常に理想的です。あまり理想的ではないのは、udevルールを作成するのがどれほど面倒なことか;)
goldilocks

@peterph収集できるものから、hda-verbはパラメーターを設定または確認するためのインターフェースを提供しますが、毎秒実行する必要があるようです。
テレサeジュニア

@goldilocksヘッドフォンを接続しても、udevイベントは送信されません。それとも私が不足しているものがありますか?
テレサeジュニア

回答:


10

私が探しているのは、ファイルの変更の通知を取得するいくつかの方法です[proc]

ファイルではないため、できません。これはまったく重複した質問ではありませんが、ここでの答えはその理由を説明しています。

/procカーネルインターフェイスです。そこには実際のファイルがないため、変更できません。ハンドルからの読み取りは要求であり、読み取り時のファイル内のデータはそれに対する応答です。

このようなことをシミュレートできる唯一の方法は、ファイルを定期的に読み取り、内容を比較して、カーネルからの応答が変更されたかどうかを確認することです。

statファイルをprocfsする場合、atimeとmtimeは同じになります。一部のファイルではstat呼び出しが行われたときは常に、他のファイルではシステム起動時からの時間です。前者の場合は常に変更されているように見え、後者の場合は変更されていないように見えます。


残念ながら、毎秒ポーリングしても、かなりのレイテンシー(例:500ms)が追加されます。これをより速く/より効率的に行う方法があればいいのですが、topのようなアプリも同じように行うと述べたので、そのままにしておきます。
テレサジュニア

@Teresaeジュニア。しかし、それはたくさんのように思えます。私はbashスクリプトのプロファイルを作成したことがないため、ここで何が正常かはわかりません(うーん...別の質問)。awk == fork()を呼び出すと、そのようなものは高価です。前述のように、すべてCで書かれたユーティリティには、より高速なメソッドがあります。私はまだあなたがシステム全体に大きな負荷を加えているとは思わない。
goldilocks

1
いいえ、申し訳ありませんが、実際には次のことを意味します。ヘッドフォンを接続してから次のスリープまで、顕著な遅延があります。しかし、私は睡眠時間を減らすつもりはありません。ご協力いただきありがとうございます!
テレサeジュニア

4

PulseAudioを使用している場合、pactl subscribeこれを行います。


はい、確かに!いくつかのオーディオの問題のため、数か月前にPA 4.0をコンパイルしてから使用し始めました。Debian Stableのバージョンは2.0です(最近は4.0をバックポートにアップロードしました)が、subscribe2.0 にはありませんでした。
テレサeジュニア

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.