killing Parent process along with child process using SIGKILL - linux

I am writing one shell script in which I have parent process and it has child processes which are created by sleep & command. Now I wish to kill the parent process so that the child process will be also killed. I was able to do that this with below command:
trap "kill $$" SIGINT
trap 'kill -HUP 0' EXIT
trap 'kill $(jobs -p)' EXIT
These commands are working with kill [parent_process_ID] commands but if I use kill -9 [parent_process_ID] then only the parent process will be killed.
Please guide me further to achieve this functionality so that when I kill parent process with any command then child process should be also killed.

When you kill a process alone, it will not kill the children.
You have to send the signal to the process group if you want all processes for a given group to receive the signal.
kill -9 -parentpid
Otherwise, orphans will be linked to init.
Child can ask kernel to deliver SIGHUP (or other signal) when parent dies by specifying option PR_SET_PDEATHSIG in prctl() syscall like this:
prctl(PR_SET_PDEATHSIG, SIGHUP);
See man 2 prctl for details.

Sending the -9 signal (SIGKILL) to a program gives no chance for it to execute its own signal handlers (e.g., your trap statements). That is why the children don't get killed automatically. (In general, -9 gives no chance for the app to clean up after itself.) You have to use a weaker signal to kill it (such as SIGTERM.)
See man 7 signal for details.

Related

Suspended child process exit if parent process exit

I have the following process tree
test1.sh
\- test2.sh
\- sleep 600
Normally If I kill the test1.sh process, the child processes test2.sh and sleep 600 will continue running. But If I suspend the sleep 600 process through send signal (SIGSTOP or SIGTSTP), and then kill the test1.sh process, the child test2.sh and sleep 600 will exit. Why?
Here is my test program:
test1.sh
#!/bin/sh
./test2.sh
test2.sh
#!/bin/sh
sleep 600
Test steps:
run test1.sh
$ ./test1.sh
open new console and suspend the child process.
$ kill -19 < sleep pid > or kill -20 < sleep pid >
kill the parent process test1.sh
$ kill < test1.sh pid >
You will find the after step3, the test2.sh and sleep 600 exited.
Bug if I only run step1 and step3, ignore step2, the test2.sh and sleep 600 process will not exit.
Can anyone explain this? Many thanks.
When you are killing process test1.sh, you leave test2.sh orphan so you need to know what happens with orphan processes in your Operating System.
When process test2.sh is running and his parent dies, the OS moves it to the init process and keeps its execution. So the result is both, test2.sh and sleep processes are still up even if you have killed test1.sh.
When process sleep is stopped (signal 20) and his parent dies, the OS tries to move it to the init process. However, since the process is stopped and there will no longer be any tty capable of resuming it (since its parent has died), the OS may decide to do other things with the process. In your case, it dies with SIGKILL to avoid the problem of many stopped, orphaned processes lying around the system. Since the sleep process have exited, the test2.sh process ends too.
From the GNU man page:
While a process is stopped, no more signals can be delivered to it
until it is continued, except SIGKILL signals and (obviously) SIGCONT
signals. The signals are marked as pending, but not delivered until
the process is continued. The SIGKILL signal always causes termination
of the process and can’t be blocked, handled or ignored. You can
ignore SIGCONT, but it always causes the process to be continued
anyway if it is stopped. Sending a SIGCONT signal to a process causes
any pending stop signals for that process to be discarded. Likewise,
any pending SIGCONT signals for a process are discarded when it
receives a stop signal.
When a process in an orphaned process group (see Orphaned Process
Groups) receives a SIGTSTP, SIGTTIN, or SIGTTOU signal and does not
handle it, the process does not stop. Stopping the process would
probably not be very useful, since there is no shell program that will
notice it stop and allow the user to continue it. What happens instead
depends on the operating system you are using. Some systems may do
nothing; others may deliver another signal instead, such as SIGKILL or
SIGHUP. On GNU/Hurd systems, the process dies with SIGKILL; this
avoids the problem of many stopped, orphaned processes lying around
the system.
By the way, if you are willing to kill them always you can add a trap on the main process to capture signals and exit the children properly.

How to kill a process by its pid in linux

I'm new in linux and I'm building a program that receives the name of a process, gets its PID (i have no problem with that part) and then pass the PID to the kill command but its not working. It goes something like this:
read -p "Process to kill: " proceso
proid= pidof $proceso
echo "$proid"
kill $proid
Can someone tell me why it isn't killing it ? I know that there are some other ways to do it, even with the PID, but none of them seems to work for me. I believe it's some kind of problem with the Bash language (which I just started learning).
Instead of this:
proid= pidof $proceso
You probably meant this:
proid=$(pidof $proceso)
Even so,
the program might not get killed.
By default, kill PID sends the TERM signal to the specified process,
giving it a chance to shut down in an orderly manner,
for example clean up resources it's using.
The strongest signal to send a process to kill without graceful cleanup is KILL, using kill -KILL PID or kill -9 PID.
I believe it's some kind of problem with the bash language (which I just started learning).
The original line you posted, proid= pidof $proceso should raise an error,
and Bash would print an error message about it.
Debugging problems starts by reading and understanding the error messages the software is trying to tell you.
kill expects you to tell it **how to kill*, so there must be 64 different ways to kill your process :) They have names and numbers. The most lethal is -9. Some interesting ones include:
SIGKILL - The SIGKILL (also -9) signal forces the process to stop executing immediately. The program cannot ignore this signal. This process does not get to clean-up either.
SIGHUP - The SIGHUP signal disconnects a process from the parent process. This an also be used to restart processes. For example, "killall -SIGUP compiz" will restart Compiz. This is useful for daemons with memory leaks.
SIGINT - This signal is the same as pressing ctrl-c. On some systems, "delete" + "break" sends the same signal to the process. The process is interrupted and stopped. However, the process can ignore this signal.
SIGQUIT - This is like SIGINT with the ability to make the process produce a core dump.
use the following command to display the port and PID of the process:
sudo netstat -plten
AND THEN
kill -9 PID
Here is an example to kill a process running on port 8283 and has PID=25334
You have to send the SIGKILL flag with the kill statement.
kill -9 [pid]
If you don't the operating system will choose to kill the process at its convenience, SIGKILL (-9) will tell the os to kill the process NOW without ignoring the command until later.
Try this
kill -9
It will kill any process with PID given in brackets
Try "kill -9 $proid" or "kill -SIGKILL $proid" commands. If you want more information, click.
Based on what you have there, it looks like you aren't getting the actual PID in your proid variable. If you want to capture the output of pidof, you will need to enclose that command in backtics for the old form of command substitution ...
proid=`pidof $proceso`
... or like so for the new form of command substitution.
proid=$(pidof $proceso)
I had a similar problem, only wanting to run monitor (Video surveillance) for several hours a day.
Wrote two sh scripts;
cat startmotion.sh
#!/bin/sh
motion -c /home/username/.config/motion/motion.conf
And the second;
cat killmotion.sh
#!/bin/sh
OA=$(cat /var/run/motion/motion.pid)
kill -9 $OA
These were called from crontab at the scheduled time
ctontab -e
0 15 * * * /home/username/startmotion.sh
0 17 * * * /home/username/killmotion.sh
Very simple, but that's all I needed.

Child process to kill its parent whithout terminating itself

How can I kill parent process script from child process script, without terminating child process in Linux.
If your shell defines PPID, kill $PPID will kill the parent. If your shell does not define PPID, you can probably get it with PPID=$( ps -o ppid= $$ ). There is no reason for this action to kill the child.

How to make sure that a process was killed? (using kill command)

I try to kill a process with the kill command in linux. (not using -9 as argument)
I need to make sure that the process is really killed.
As far as I know, the kill command runs asynchronously and it can take some time till it is finished.
I need to make sure, after I run the kill that my process has died using bash
Can you please assist?
Thanks!!!
Killing a process with signal 0 will check if the process is still running, and not actually kill it. Just check the return code.
Assuming $PID holds the pid of your process, you could do something like this:
kill "$PID"
while [ $(kill -0 "$PID") ]; do
sleep 1
done
echo "Process is killed"
kill is used to send signals to processes. It doesn't necessarily terminate the process (but usually do). kill without explicitly mentioned signal will send SIGTERM to the process. The default action on SIGTERM is to terminate process but process can setup a different signal handler and process might not be terminated.
What, I think you need, is a way to find if the process has handled the signal or not. This can be done using ps s $PID. If this shows 0s as pending mask, the process has received the signal and processed it.

does linux kill command terminate child processes?

When you invoke "kill" on a parent process, are the child processes subsequently killed as well?
No, not automatically.
Commonly, when a parent is killed the child will be sent a HUP signal. At least this is true when the parent is a shell. I'm not sure about if this comes for free whenever a child was fork()ed.
But this can be defeated, for instance if the parent is a shell and the child was started using nohup child&, or if the child itself declared that it would ignore HUP signals.
man 2 kill
int kill(pid_t pid, int sig);
If pid is greater than 0, sig shall be sent to the process whose process ID is equal to pid.
If pid is negative, but not -1, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal to the absolute value of pid, and for which the process has permission to send a signal.
Unless setpgid or similar function is called, a child process is in the same process group as its parent. For example, jobs started by your shell belong to the same process group as the shell itself.
Thus kill -HUP $$ sends SIGHUP to your shell, while kill -HUP -$$ sends SIGHUP to all processes in your current session, including children of your shell.
This bash script will kill itself and child processes... the opposite of nohup.
#!/bin/bash
read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
trap "kill -TERM -$pgrp; exit" EXIT TERM KILL SIGKILL
# run the program given on args
"$#"
exit $?
Does anyone know if there is a builtin like this?
Yes, it will; use kill -1 : http://unixhelp.ed.ac.uk/shell/jobz5.html

Resources