dmesgで何かが見つかった場合にプロセスを強制終了する無限ループを作成するにはどうすればよいですか?


8

一部またはすべての値を返すwhile場合dmesgは、決定されたプロセスを強制終了するループを作成する必要があります。

これが私が持っているものです。

#!/bin/bash
while [ 1 ];
do

BUG=$(dmesg | grep "BUG: workqueue lockup" &> /dev/null)

    if [ ! -z "$BUG" ]; then
   killall someprocessname

else
    break
    fi
    done

代わりに! -zやるべきかわからない[ test -n "$BUG" ]

-nを使用すると、バイナリを期待することについて何かが示されます。

BUGのロックアップがすべてのプロセスを停止するため、スクリプトが機能するかどうかはわかりませんがdmesg、コンピューターが完全に停止するまでにはまだ数行あります。おそらく、追いつき、プロセスを強制終了できます。


2
dmesg全体を取得するので、検索された文字列が1回出現すると、毎回それが表示されないため、各ループでkillallが実行されます。(@ l0b0が言及した他の事項(睡眠/ペーシングの欠如など)に加えて)
Olivier Dulac 2018

回答:


12

いくつかの問題:

  • これをビジーループで実行すると、可能な限り多くのリソースが消費されます。これは、sleepINGが正当化されると考えられる1つの例です。
  • ただし、の最近のバージョンにdmesgは、出力を追跡するフラグがあるため、全体を(テストされていない)として書き換えることができます

    while true
    do
        dmesg --follow | tail --follow --lines=0 | grep --quiet 'BUG: workqueue lockup'
        killall someprocessname
    done
    
  • コードは読みやすいようにインデントする必要があります。
  • それは本当に奇妙[ですが、同じですtest-参照してくださいhelp [

1
-qgrep -q 'searchstring終了してdmesg --follow、検索文字列が1回出現するとすぐに次の行に到達できるように追加するつもりですか?それがなければあなたのループは殺人鬼にもループにも到達しませんか?
Olivier Dulac

1
そして、-qを使用しても、dmesg --followがdmesgコンテキストの数行を表示する(したがって、以前の発生を表示する)場合、あなたがたくさん殺してしまうのではないかと恐れています。
Olivier Dulac

@OlivierDulac後者の問題はで対処する必要がありtailます。
l0b0

何をしtail --lines=0ますか?それが他の値に対して何を意味するか私は知っています。
ジョー

1
@Joeこれはマニュアルページにあります- --followコマンドの開始後に到着する行だけが続きます(つまり、印刷されます)。
l0b0

9

@ l0b0の答えの変形:

dmesg --follow | awk '
   /BUG: workqueue lockup/  { system ("killall someprocessname") ; rem="done at each occurrence. You could add further things, like print to a logfile, etc.,"
        }'

これでループを実行してみましょう。これにはいくつかの利点があります。

  • そのプロセスが死ぬまで機能します。
  • またkillall、検索文字列 "BUG:workqueue lockup"が発生するたびに1つを超える呼び出しは行われません。これにより、他の回答が改善されます。

テストするには:あなたが名前のスクリプトにこれを置くことができるthescript、とやるnohup thescript &ので、それはthescriptあなたがあなたのセッションを終了した後も実行し続けます。

満足のいく結果が得られたら、それを強制終了し、(シェルを使用して毎回実行する代わりにnohupdaemon script現在のランレベルで開始できるに変換できます。

すなわち:モデルとして別のスクリプトを使用して、あなたが変更することができます(少なくとも開始、停止およびステータスのセクションを持っている必要があります)thescript適切にして、内に配置し/etc/rc.d/init.d、そしてそれが命名にシンボリックリンクを持ってSxxthescript適切な(S)の下で/etc/rc.d/rcNNというA通常のランレベルの番号(who -a現在のランレベルを知るには、上の行を参照してください)。またKxxthescript、すべての(またはほぼすべての)ランレベルに適切なシンボリックリンクを設定して、ランレベルを切り替えるときにスクリプトが適切に強制終了されるようにします。

または、「適切なこと」を実行して、systemdまたはディストリビューションが使用する同等のシステムを介して実行/停止します。


@誰も:私は嬉しいです。さらに回答(または現在の回答の変更)を許可するために開いたままにしておく必要があると感じない限り、どちらの回答もあなたの意見で最高と思われるものを「受け入れる」(緑色のチェックマーク)を忘れないでください。
Olivier Dulac

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