Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Kill Current Command When Bash Script is Killed

I current have a script that looks like this.

# code

mplayer "$vid"

# more code

The problem is that if this script is killed the mplayer process lives. I wondering how I could make it so that killing the script would kill mplayer as well.

I can't use exec because I need to run commands after mplayer.

exec mplayer "$vid"

The only possible solution I can think of is to spawn it in the background and wait until it finishes manually. That way I can get it's PID and kill it when the script gets killed, not exactly elegant. I was wondering what the "proper" or best way of doing this is.

like image 879
Kevin Cox Avatar asked Dec 20 '22 14:12

Kevin Cox


2 Answers

I was able to test the prctl idea I posted about in a comment and it seems to work. You will need to compile this:


#include "sys/prctl.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"

int main(int argc, char ** argv){

  prctl(PR_SET_PDEATHSIG, atoi(argv[1]),0,0,0);

  char * argv0 = strdup(argv[2]);

  char * slashptr = strrchr(argv0, '/');
  if(slashptr){
    argv0 = slashptr + 1;
  }

   return execvp(argv0, &(argv[2]));



}

Let's say you have compiled the above to an executable named "prun" and it is in your path. Let's say your script is called "foo.sh" and it is also in your path. Make a wrapper script that calls

prun 15 foo.sh

foo.sh should get SIGTERM when the wrapper script is terminated for any reason, even SIGKILL.

Note: this is a linux only solution and the c source code presented is without detailed checking of arguments

like image 83
frankc Avatar answered Dec 28 '22 08:12

frankc


Thanks to Mux for the lead. It appears that there is no way to do this in bash except for manually catching signals. Here is a final working (overly commented) version.

trap : SIGTERM SIGINT # Trap these two (killing) signals.  These will cause wait
                      # to return a value greater than 128 immediately after received.

mplayer "$vid" & # Start in background (PID gets put in `$!`)
pid=$!

wait $pid # Wait for mplayer to finish.
[ $? -gt 128 ] && { kill $pid ; exit 128; } ; # If a signal was recieved
                                              # kill mplayer and exit.

Refrences: - traps: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html

like image 23
2 revs Avatar answered Dec 28 '22 07:12

2 revs