4

I am using a simple dbus-monitor script for gnote. The script starts when gnote starts. I modified Exec= -line of the .desktop file to achieve this.

The problem is that I didn't find any way to kill my script after the application(i.e gnote) exits. If the application itself exits there is no point to keep script running in the background as it is not going to fetch any output.

The script looks like this:

#!/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

I tried to modify it like this :

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

But it didn't work. I also tried using trap as explained in this question but without success.

2 Answers2

2

The issue

...is that your dbus- monitor script runs a child- process (dbus-monitor) which is not killed with the script, actually making the script "un- killable".

What to do

What you need to do is use a wrapper, running gnote + the monitor script, then when gnote ends, kill the dbus-monitor- script by the command:

pkill -P <pid>

...where <pid> is the pid of your monitor script (I used pgrep -f /path/to/script) . This will kill the script and its children, terminating it successfully.

I ran into exactly the same issue writing this answer.

The wrapper

Assuming your monitor script is executable, run gnote by the command:

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

The easyest is to make it a one- liner script and start the script from your .desktop -file

Jacob Vlijm
  • 83,767
  • This is not working for me. It seems pgrep -f is failing. Also it doesn't work if there are more than one script running. However I made it work by changing it like this: '/path/to/monitorscript' & gnote && killall "/path/to/monitorscript" – Khurshid Alam Sep 08 '16 at 06:25
  • '/path/to/monitorscript' & gnote && killall dbus-monitor – Khurshid Alam Sep 08 '16 at 06:32
1

Consider having a function in background that will poll pgrep for gnote's pid, and once PID stop the dbus-monitor ( note the use of -f flag with pkill ). Also , notice how the background function is called - stop_monitor &

I've modified your script to include such function. Installed gnote, tested on Ubuntu 16.04 , works as expected.

#!/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
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • Thanks. This is working. But infinite loop is causing the process to go over 35 MB over time...not sure why. I am using while sleep 10 which is also working without cpu/memory hog. – Khurshid Alam Sep 08 '16 at 06:10
  • @KhurshidAlam by 35 MB you mean 35 MB of RAM ? or are you redirecting output to file ? Also, with the while loop in the stop_monitor function, consider adding sleep 0.25 . – Sergiy Kolodyazhnyy Sep 08 '16 at 06:27
  • Also, if this answer is working for you, consider marking it as accepted or at least leave an upvote to express that this answer is useful. Again, up to your consideration – Sergiy Kolodyazhnyy Sep 08 '16 at 06:28
  • Redirecting?....Yes...only redirecting standard output and error to system log. exec 1> >(logger -s -t $(basename $0) 2>&1) and exec 2> >(logger -s -t $(basename $0)) But it's not that important. I can remove this. – Khurshid Alam Sep 08 '16 at 09:41
  • I like the above method using wrapper. So I have accepted that as an answer. But this one works too. Thanks. – Khurshid Alam Sep 08 '16 at 09:45