web-dev-qa-db-fra.com

Comment puis-je tuer un script de moniteur dbus lorsqu'une application se ferme?

J'utilise un simple script dbus-monitor pour gnote. Le script démarre lorsque gnote commence. J'ai modifié Exec= -line du fichier .desktop pour y parvenir.

Le problème est que je n’ai trouvé aucun moyen de tuer mon script après la fermeture de l’application (c.-à-d. gnote ). Si l'application elle-même se ferme, il est inutile de laisser le script s'exécuter en arrière-plan, car il ne récupère aucune sortie.

Le script ressemble à ceci:

#!/bin/bash 


OJECT="'org.gnome.Gnote'" 
IFACE="'org.gnome.Gnote.RemoteControl'" 
DPATH="'/org/gnome/Gnote/RemoteControl'" 
echo $IFACE


WATCH1="type='signal',sender=${OJECT},interface=${IFACE},path=${DPATH},member='NoteAdded'" 
WATCH2="type='signal',sender=${OJECT},interface=${IFACE},path=${DPATH},member='NoteSaved'" 
WATCH3="type='signal', sender=${OJECT}, interface=${IFACE}, path=${DPATH}, member='NoteDeleted'"

dbus-monitor ${WATCH2} | 
while read LINE; do
  echo $LINE | grep "note://"
done

J'ai essayé de le modifier comme ceci:

dbus-monitor ${WATCH2} | 
while read LINE; do
  echo $LINE | grep "note://"
  if pgrep "gnote" > /dev/null; then
    echo ""
  else
    break;
  fi
done

pid=`pidof -x $(basename $0)`
kill $pid

Mais ça n'a pas marché. J'ai aussi essayé d'utiliser trap comme expliqué dans cette question mais sans succès.

3
Khurshid Alam

Le problème

... est que votre script dbus-monitor exécute un processus enfant (dbus-monitor) qui n'est pas tué avec le script, ce qui le rend "impossible à tuer".

Que faire

Ce que vous devez faire est d'utiliser un wrapper, exécutant gnote + le script du moniteur, puis lorsque gnote se termine, tuez le script dbus-monitor- à l'aide de la commande:

pkill -P <pid>

... où <pid> est le pid de votre script de moniteur (j'ai utilisé pgrep -f /path/to/script). Cela va tuer le script et ses enfants, en le terminant avec succès.

J'ai rencontré exactement le même problème en écrivant cette réponse .

Le wrapper

En supposant que votre script de moniteur soit exécutable, exécutez gnote à l'aide de la commande suivante:

'/path/to/monitorscript' & gnote && pkill -P "$( pgrep -f '/path/to/monitorscript )"

Le plus simple est d'en faire un script à ligne unique et de le démarrer à partir de votre fichier .desktop

2
Jacob Vlijm

Pensez à avoir une fonction dans background qui interrogera pgrep pour le pid de gnote, et une fois que PID arrêtera le dbus-monitor (notez l'utilisation de -f flag avec pkill). Notez également comment la fonction d’arrière-plan est appelée - stop_monitor &

J'ai modifié votre script pour inclure une telle fonction. Gnote installé, testé sur Ubuntu 16.04, fonctionne comme prévu.

#!/bin/bash 

stop_monitor()
{
    while pgrep "gnote" > /dev/null
    do
       :
    done

    pkill -f "dbus-monitor"
}

OJECT="'org.gnome.Gnote'" 
IFACE="'org.gnome.Gnote.RemoteControl'" 
DPATH="'/org/gnome/Gnote/RemoteControl'" 
echo $IFACE


WATCH1="type='signal',sender=${OJECT},interface=${IFACE},path=${DPATH},member='NoteAdded'" 
WATCH2="type='signal',sender=${OJECT},interface=${IFACE},path=${DPATH},member='NoteSaved'" 
WATCH3="type='signal', sender=${OJECT}, interface=${IFACE}, path=${DPATH}, member='NoteDeleted'"

stop_monitor &

dbus-monitor ${WATCH2} | 
while read LINE; 
do
    echo $LINE | grep "note://"
done
1