5 votes

Détecter les commandes longues et notifier lorsqu'elles sont terminées

C'est un pari risqué - je ne pense pas que ce soit possible, mais je me suis dit que je demanderais.

Je lance fréquemment des commandes qui prennent quelques minutes à s'exécuter, et pendant qu'elles tournent, je consulte mes e-mails ou navigue sur Internet. Quand je m'en souviens, j'exécute commande; terminé, où terminé est une commande qui affiche une boîte de dialogue me notifiant que la commande est terminée. Cependant, je n'y pense pas toujours, donc j'aimerais avoir quelque chose qui détecte automatiquement quand une commande prend plus de N secondes et exécute terminé une fois le processus terminé. Si cela a de l'importance, je préfère utiliser zsh mais je changerais de shell si un autre était capable de le faire.

iTerm (un émulateur de terminal pour OSX) a une fonctionnalité de ce type, où il vous montre une notification lorsque le terminal devient inactif ou produit une sortie après avoir été inactif pendant un certain temps. Si vous connaissez des émulateurs de terminal pour Linux qui possèdent cette fonctionnalité, cela fonctionnerait tout aussi bien (ou mieux).

Pouvez-vous penser à un moyen de faire fonctionner cela ? Merci beaucoup !

4voto

Robert Vabo Points 158

Vous avez besoin d'un moyen de trouver vos processus qui tournent depuis un certain temps. Pour ce faire, il est utile de savoir que le paramètre etime affiche le temps écoulé depuis le démarrage du processus, dans le format DD-hh:mm:ss, où chaque partie plus grande est facultative. Ainsi, vous pouvez faire

ps -U sauer -o etime,pid,command

(sur AIX, vous pourriez utiliser ps -U sauer -o "%t,%p,%c")

Vous pourriez utiliser un -t $( tty) à la place du -U nom_utilisateur pour sélectionner les processus sur le tty actuel (c'est-à-dire, dans le terminal actuel). C’est ce que je ferai plus tard. Notez également que l'utilisation de -o cmd= supprime l'en-tête de colonne, mais cela signifie que vous avez besoin de plusieurs options -o.

Donc, vous finirez par avoir ps -t $(tty) -o etime= -o pid= -o command= pour afficher tous les processus en cours d'exécution sur le terminal actuel, en affichant les colonnes "temps écoulé depuis le démarrage", "identifiant de processus" et "commande", et en supprimant les en-têtes de colonne.

Maintenant, vous devez obtenir uniquement ceux qui tournent depuis plus de X secondes. Vous devez donc extraire la première colonne et convertir le temps en secondes. Que diriez-vous d'un script shell pour cela (ksh/bash) :

ps -t $(tty) -o etime= -o pid= -o command= | while read time pid cmd
do
  secs=0
  while true
  do
    part=${time##*:}
    secs=$(( secs + ${part#0} ))
    [[ "$part" != "$time" ]] || break # n'avait que des secondes

    time=${time%:$part}
    part=${time##*:}
    secs=$(( secs + (60 * ${part#0}) ))
    [[ "$part" != "$time" ]] || break # il ne restait que les minutes

    time=${time%:$part}
    part=${time##*-}
    secs=$(( secs + (60 * 60 * ${part#0}) ))
    [[ "$part" != "$time" ]] || break # il ne restait que les heures

    time=${time%-$part} # il ne reste que les jours-heures
    secs=$(( secs + (24 * 60 * 60 * time) ))
    break
  done

  echo "Le processus '$cmd' (pid '$pid') est en cours depuis '$secs' secondes"
done

Un couple de choses pourrait nécessiter des explications. Le ${part#0} est là pour que des temps comme "06" secondes soient convertis en "6" au lieu d'être traités comme octaux. Bien sûr, 06 en octal et 6 en décimal sont identiques, mais 09 en octal n'est pas valide, et parfois les shells se plaignent de cela.

L'autre chose est que ${var##*:} évalue tout ce que $var contient avec la plus grande chaîne correspondant à "*:" élaguée depuis le début (un seul # est la correspondance la plus courte, et %% / % fait la même chose depuis la fin). Si le motif ne correspond pas, il évalue à $var. Nous arrachons donc tout sauf les secondes, ajoutons cela aux secondes, puis supprimons les secondes à la fin. S'il nous reste quelque chose, ce sont des minutes. Nous arrachons donc les minutes, convertissons en secondes, ajoutons au total en cours, élaguons la fin. Et ainsi de suite.

D'accord. Ensuite, vous devez simplement ajouter un #!/bin/ksh (ou bash, si nécessaire) en haut, et vous avez un script. Sauf qu'il vous faut également un moyen de trouver uniquement les pids qui fonctionnent depuis plus de X secondes. Que diriez-vous d'un fichier dans /tmp. Utilisons ceci à la place de la commande echo :

  if [[ $secs -gt 120 ]]
  then
    { cat /tmp/pids.$$; echo "$pid $cmd"; } 2>/dev/null | sort -u > /tmp/pids.$$.tmp
    while read p c
    do
      if ps -p $p >/dev/null 2>&1
      then
        # le remettre dans la liste
        echo "$p $c" > /tmp/pids.$$
      else
        echo "La commande '$c' s'est arrêtée" | mailx -s "rapport de sortie" $USER
      fi
    done < /tmp/pids.$$.tmp
  fi

À présent, il ne vous reste plus qu'à envelopper toute cette énorme chose à l'intérieur d'une boucle while

while true do # la grande boucle while et la déclaration if sleep 10 done

Appelez-le process_monitor.sh et placez un process_monitor.sh& dans votre .profile ou .bash_login ou autre. Il restera en arrière-plan à surveiller tous les processus dans ce terminal, et lorsque vous trouverez l'un d'eux en cours depuis plus de 120 secondes, il sera ajouté à la liste à surveiller, et vous recevrez un e-mail lorsque le processus se termine.

Il reste des choses que j'ajouterais probablement pour le rendre plus attrayant, comme le piégeage du signal EXIT et la suppression des fichiers temporaires lorsque le script se termine, etc. Mais c'est un exercice pour vous. J'espère que cela devrait suffire pour vous mettre sur la bonne voie. :)

2voto

John P. Fisher Points 225

J'ai simplement essayé une petite application qui fait exactement ce que vous désirez : https://github.com/jml/undistract-me disponible dans le monde Debian/Ubuntu en tant que package. Ça n'a pas fonctionné pour moi avant que je redémarre Konsole, qui est mon application de terminal à onglets préférée.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X