How to Make shell scripts stop and shell scripts stop
Sometimes the shell script we write contains some background tasks. When the script process has been executed to the end and exited, these background tasks are directly linked to the init/systemd process, instead of stopping as the script exits.
For example:
[root@mariadb ~]# cat test1.sh #!/bin/bashecho $BASHPIDsleep 50 &[root@mariadb ~]# ps -elf | grep slee[p]0 S root 10806 1 0 80 0 - 26973 hrtime 19:26 pts/1 00:00:00 sleep 50
As you can see from the results, after the script exits, the parent process of the sleep process changes to 1, that is, it is mounted under the init/systemd process.
In this case, we can directly use the kill command in the script to kill the sleep process.
[root@mariadb ~]# cat test1.sh #!/bin/bashecho $BASHPIDsleep 50 &kill $!
However, if the sleep process is in a loop, it will be troublesome.
For example, in the following example, killing sleep, killing the script's own process, letting the script automatically exit, or even running exec to exit the current script shell is invalid.
[root@mariadb ~]# cat test1.sh #!/bin/bashecho $BASHPIDwhile true;do sleep 50 echo 1done &killall sleepkill $BASHPID
Because sleep loops in while, after sleep is killed, a sleep will be generated later. The script itself is killed, the script is automatically exited, or the exec is used. Because of the existence of loops, it will re-fork a script process. Note that the cyclic process will not be attached to the init/systemd process, but to a new script process.
[root@mariadb ~]# ./test1.sh 10859./test1.sh: line 7: 10862 Terminated sleep 50Terminated1[root@mariadb ~]# pstree -p | grep sleep |-test1.sh(10860)---sleep(10863)
The result shows that the 10859 process of test1.sh is killed by itself, but a 10860 test1.sh process is re-generated, and the continuously generated sleep process is always under test1.sh.
Unless we manually kill the newly generated test1.sh, this script will go through infinite loops. But isn't it very troublesome?
So how to implement "script suicide "? In fact, it is very easy to use the killall command to kill the script process before the script exits.
[root@mariadb ~]# cat test1.sh #!/bin/bashecho $BASHPIDwhile true;do sleep 50 echo 1done &killall `basename $0`
In this way, before the script exits, when the kernel prepares to fork the new test1.sh process to take over the sleep process in the background while, killall will also kill the new test1.sh, in this way, the background process will disappear along with test1.sh.
The key point here is,When a script contains a cyclic background task, the script exits: (1) the script is ready to exit --> (2) the new kernel fork script process is used to take over the background cyclic tasks in the script --> (3) the new script process takes over the background task --> (4) the old script process disappears.Killall killed both the new and old script processes before step (3), which successfully killed the script process.
Back to Linux series article outline: http://www.cnblogs.com/f-ck-need-u/p/7048359.html
Back to website architecture series article outline: http://www.cnblogs.com/f-ck-need-u/p/7576137.html
Back to database series article outline: http://www.cnblogs.com/f-ck-need-u/p/7586194.html
Reprinted please indicate the source: http://www.cnblogs.com/f-ck-need-u/p/8661501.html
Note: If you think this article is not bad, please click the recommendation in the lower right corner. Your support can stimulate the author's enthusiasm for writing. Thank you very much!