How to kill the current command When Bash Script is killed

I current has a script that looks like this.

# code mplayer "$vid" # more code 

The problem is that if this script is killed, the mplayer process will work. I am wondering how can I do this to kill a script would also kill mplayer.

I cannot use exec because I need to run commands after mplayer.

 exec mplayer "$vid" 

The only possible solution I can think of is to create it in the background and wait for it to end manually. That way I can get the PID and kill it when the script is killed, and not quite elegantly. I was wondering what the β€œright” or best way to do this is.

+4
source share
5 answers

I was able to test the prctl idea that I wrote about in the 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])); }
#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 compiled the above for an executable file named "prun", and it is in your path. Let's say your script is called "foo.sh" and it is also in your way. Create a wrapper script that calls

prun 15 foo.sh

foo.sh should get SIGTERM when the shell script terminates for any reason, even SIGKILL.

Note: this solution is for Linux only, and the source code c is presented without verifying the arguments in detail

+4
source

Thanks to Mux for the leadership. There seems to be no way to do this in bash, except for manually capturing signals. Here is the final work (too commented out) 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

+3
source

( Updated ) I think I understand what you are looking for now:

You can accomplish this by creating a new terminal to run the script:

 gnome-terminal -x /path_to_dir_of_your_script/your_script_name 

(or use xterm -e or konsole -e instead of gnome-terminal -x , depending on which system you are on)

So, whenever your script ends / terminates (I assume that you have exit 0 or exit 1 in some parts of the script), the newly created terminal will also exit with the completion of the script, which in turn will also destroy any applications created in this new terminal.

For example, I just tested the above command with this script:

 #!/bin/bash gedit & pid=$! echo "$pid" sleep 5 exit 0 

As you can see, there are no explicit calls to kill the new gedit process, but the application (gedit) closes as soon as the script exits.

(Previous answer: alternatively, if you were just asking how to kill the process) Here is a brief example of how you can do this with kill .

 #!/bin/bash gedit & pid=$! echo "$pid" sleep 5 kill -s SIGKILL $pid 

If I do not understand your question, you can immediately receive a PID response process, and not wait until it ends.

+2
source

Well, you can just kill a process group so that the whole process tree is killed, first find out the group id

 ps x -o "%p %r %c" | grep <name> 

And then use kill as follows:

 kill -TERM -<gid> 

Note the dash in front of the process group identifier. Or single line:

 kill -TERM -$(pgrep <name>) 
+2
source

Perhaps use command substitution to run mplayer "$vid" in a subshell:

 $(mplayer "$vid") 

I tested it like this:

tesh.sh:

 #!/bin/sh $vid = "..." $(mplayer "$vid") 

 % test.sh 

In a separate terminal:

 % pkill test.sh 

In the source terminal mplayer stops, printing to stderr

 Terminated MPlayer interrupted by signal 13 in module: av_sync 
0
source

Source: https://habr.com/ru/post/1443980/


All Articles