Comment puis-je créer une boucle infinie qui tue un processus si quelque chose est trouvé dans dmesg?

8

J'ai besoin de créer une whileboucle qui si dmesgretourne une valeur quelconque, alors elle devrait tuer un processus déterminé.

Voici ce que j'ai.

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

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

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

else
    break
    fi
    done

Je ne sais pas si ! -zje devrais faire[ test -n "$BUG" ]

Je pense qu'avec -n cela dit quelque chose sur l'attente d'un binaire.

Je ne sais pas si le script fonctionnera même parce que le blocage de BUG arrête tous les processus, mais il reste encore quelques lignes dmesgjusqu'à ce que l'ordinateur soit complètement foutu - je peux peut-être rattraper et tuer le processus.

Personne
la source
2
Vous prenez le dmesg entier, donc une fois qu'une occurrence de la chaîne recherchée se produit, vous ne la verrez pas à chaque fois, et ainsi tuerez tout à chaque boucle! (En plus des autres choses mentionnées par @ l0b0 telles que le manque de sommeil / de stimulation, etc.)
Olivier Dulac

Réponses:

12

Quelques problemes:

  • Vous l'exécutez dans une boucle occupée, qui consommera autant de ressources que possible. Il s'agit là d'un cas où sleeping pourrait être justifié.
  • Cependant, les versions récentes de dmesgont un indicateur pour suivre la sortie , vous pouvez donc réécrire le tout en (non testé)

    while true
    do
        dmesg --follow | tail --follow --lines=0 | grep --quiet 'BUG: workqueue lockup'
        killall someprocessname
    done
  • Le code doit être en retrait pour être lisible.
  • C'est vraiment étrange, mais [c'est la même chose que test- voyez help [.
l0b0
la source
1
Vouliez-vous ajouter -qpour que les grep -q 'searchstringsorties de la dmesg --followet ainsi laisser la ligne suivante être atteinte dès qu'il voit une occurrence de la chaîne de recherche? Sans cela, votre boucle n'atteindra pas le killall ni la boucle?
Olivier Dulac
1
Et même avec -q, je crains que vous ne tuiez beaucoup, si dmesg --follow montre quelques lignes de contexte dmesg (et montre donc les occurrences précédentes), d'où ma réponse proposée en variante.
Olivier Dulac
@OlivierDulac Ce dernier problème doit être résolu avec le tail.
l0b0
Que fait tail --lines=0-il? Je sais ce que cela signifie pour toute autre valeur.
Joe
1
@Joe C'est dans la page de manuel - avec --followelle suit (c'est-à-dire, imprime) uniquement les lignes arrivant après le démarrage de la commande.
l0b0
9

Une variante de la réponse de @ 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.,"
        }'

Cela nous permet de faire le bouclage, ce qui présente certains avantages:

  • cela fonctionnera jusqu'à la fin de ce processus.
  • Il n'appelle pas plus de 1 killallpar occurrence de la chaîne de recherche "BUG: workqueue lockup", ce qui améliore l'autre réponse.

Pour tester: Vous pouvez mettre cela dans un script nommé thescript, et faire nohup thescript &, afin que thescriptcela continue même après avoir quitté votre session.

Une fois que vous êtes satisfait, cela fonctionne, tuez-le, puis vous pouvez (au lieu de l'exécuter à chaque fois dans un shell avec nohup) le transformer en un daemon scriptque vous pouvez ensuite avoir démarré dans votre niveau d'exécution actuel.

c'est-à-dire: en utilisant un autre script comme modèle (vous devez avoir au moins les sections start, stop et status), vous pouvez le modifier de thescriptmanière appropriée, puis le placer à l'intérieur /etc/rc.d/init.d, et avoir un lien symbolique vers celui-ci nommé Sxxthescriptsous le (s) approprié (s) /etc/rc.d/rcN, Nétant un numéro de votre niveau d'exécution normal (voir les premières lignes de who -apour connaître le niveau d'exécution actuel). Et disposez également des Kxxthescriptliens symboliques appropriés , dans tous les niveaux d'exécution (ou presque), afin que le script soit correctement supprimé lors du changement de niveau d'exécution.

Ou faites "les choses appropriées" pour le faire fonctionner / arrêter via systemd ou tout système équivalent utilisé par votre distribution.

Olivier Dulac
la source
@Personne: je suis content. N'oubliez pas d '«accepter» (coche verte), selon vous, les réponses qui vous semblent les meilleures, sauf si vous pensez qu'il doit rester ouvert pour permettre d'autres réponses (ou des modifications des réponses actuelles).
Olivier Dulac
les deux réponses sont correctes j'aimerais pouvoir sélectionner les deux.
Personne le