Killing all child processes linux

How to kill all child processes after parent process died and they all switched to init?

I have the following problem: when my big parent process dies (accidentelly!) after it created many child processes, all child processes switched to init .

How can I safely kill all these child processes ?

and after doing it I can use this answer and kill all child processes.

Problem here is that all child’s processes switched to init and this solution does not work.

Is there a way except for htop and kill it all manually?

Thank you in advance!

3 Answers 3

  1. Short Term Workaround: If your big parent process creates all the children around the same time, sort the output of ps by STIME (process start time). That (along with the process name) will help you identify the orphans from this invocation.
  2. Long Term Fix: Modify your big parent process program to keep a log of the PIDs of all the processes that it starts. Then you can use that as a kill list.

You can make a reasonable shortlist using:

Maybe refine that by also filtering on other fields, like STIME not for your session startup, and TTY not ?, and CMD not starting with /usr/lib or /usr/bin or /lib. Put the list into a file for a final check, and then awk out column 2 | xargs | kill.

Not portable, but Linux allows for not- init reparenting of processes, see PR_SET_CHILD_SUBREAPER in prctl(2).

PR_SET_CHILD_SUBREAPER (since Linux 3.4)

      If arg2 is nonzero, set the «child subreaper» attribute of the calling process; if arg2 is zero, unset the attribute. When a process is marked as a child subreaper, all of the children that it creates, and their descendants, will be marked as having a subreaper. In effect, a subreaper fulfills the role of init(1) for its descendant processes. …

However your subreaper could also die (accidentally). Another option, again on Linux, may be a PID namespace or container. The more usual solution is to make the parent process as simple and robust as possible, so that it is less likely to be kicked over or die.

More complicated would be to link the child processes to the parent, though this may not be possible if the child processes execs something else, or if the child processes cannot be complicated with async I/O as the child will have to check the pipe for EOF to notice that the parent has gone away:

Источник

How do you kill all child processes without killing the parent

I have a script which runs a background process at the beginning, then towards the end needs to stop that background process and its children, THEN do some other tasks etc then return an error code if necessary. How do I do this? I have seen several examples of how to kill the whole tree including the parent process (eg kill 0 ) but I want the main script to continue running and return the right error code. E.g.:

2 Answers 2

You need to capture the value of $! (the child PID) right after

To expand on Ed Heal’s comment:

In the parent process, trap SIGTERM, eg

trap «echo received sigterm» SIGTERM

Then, when you want to terminate all the child processes, in the main script do

Читайте также:  Яндекс диск 2019 для windows

kill -s SIGTERM 0

The parent will also receive SIGTERM, but that doesn’t matter, since it’s trapped that signal.

You may also find it useful to set a trap for EXIT in the child processes so they can clean up when they receive SIGTERM.

You could send the child processes SIGKILL, but that’s a bit brutal, and the child processes won’t have a chance to do any clean up.

edit

Here are some scripts that illustrate how a parent script can kill its children individually, rather than en masse using kill -s SIGTERM 0 .

traptest

sleeploop

This even works if you want to pipe the output of traptest , eg try

Источник

Kill all descendant processes [duplicate]

I’m writing an application. It has the ability to spawn various external processes. When the application closes, I want any processes it has spawned to be killed.

Sounds easy enough, right? Look up my PID, and recursively walk the process tree, killing everything in sight, bottom-up style.

Except that this doesn’t work. In one specific case, I spawn foo , but foo just spawns bar and then immediately exits, leaving bar running. There is now no record of the fact that bar was once part of the application’s process tree. And hence, the application has no way of knowing that it should kill bar .

I’m pretty sure I can’t be the first person on Earth to try to do this. So what’s the standard solution? I guess really I’m looking for some way to «tag» a process in such a way that any process it spawns will unconditionally inherit the same tag.

(So far, the best I can come up with is running the application as a different user. That way, you can just indescriminently kill all processes beloning to that user. But this has all sorts of access permission problems. )

5 Answers 5

Update

This is one of those ones where I clearly should have read the question more carefully (though seemingly this is the case with most answers on to this question). I have left the original answer intact because it gives some good information, even though it clearly misses the point of the question.

Using SID

I think the most general, robust approach here (at least for Linux) is to use SID (Session ID) rather than PPID or PGID. This is much less likely to be changed by child processes and, in the case of shell script, the setsid command can be used to start a new session. Outside of the shell the setuid system call can be used.

For a shell that is a session leader, you can kill all the other processes in the session by doing (the shell won’t kill itself):

Note: The trailing equals sign in argument pid= removes the PID column header.

Otherwise, using system calls, call getsid for each process seems like the only way.

Using a PID namspace

This is the most robust approach, however the downsides are that it is Linux only and that it needs root privileges. Also the shell tools (if used) are very new and not widely available.

For a more detailed discussion of PID namespaces, please see this question — Reliable way to jail child processes using `nsenter:`. The basic approach here is that you can create a new PID namespace by using the CLONE_NEWPID flag with the clone system call (or via the unshare command).

When a process in a PID namespace is orphaned (ie when it parent process finishes), it is re-parented to the top level PID namespace process rather than the init . This means that you can always identify all the descendants of the top level process by walking the process tree. In the case of a shell script the PPID approach below would then reliably kill all descendants.

Читайте также:  Как сразу обновиться до windows

Further reading on PID namespaces:

Original Answer

Killing child processes

The easy way to do this in a shell script, provided pkill is available is:

This kills all children of the current given process ( $$ expands to the PID of the current shell).

If pkill isn’t available, a POSIX compatible way is:

Killing all descendent processes

Another situation is that you may want to kill all the descendants of the current shell process as well as just the direct children. In this case you can use the recursive shell function below to list all the descendant PIDs, before passing them as arguments to kill:

Double forks

One thing to beware of, which might prevent the above from working as expected is the double fork() technique. This is commonly used when daemonising a process. As the name suggests the process that is to be started runs in the second fork of the original process. Once the process is started, the first fork then exits meaning that the process becomes orphaned.

In this case it will become a child of the init process instead of the original process that it was started from. There is no robust way to identify which process was the original parent, so if this is the case, you can’t expect to be able to kill it without having some other means of identification (a PID file for example). However, if this technique has been used, you shouldn’t try to kill the process without good reason.

Источник

How do you kill a process tree in linux? [closed]

Want to improve this question? Update the question so it’s on-topic for Server Fault.

Closed 10 years ago .

Sometimes, sending a SIGTERM to a process will cause it to send SIGTERM to all its child processes. However, sometimes this doesn’t work.

Is there a command or a utility that will allow me to kill a process and all its child processes at the same time? I usually resort to manually collecting all the pids into one kill command, but it feels stupid.

This SO question asks how to do this with perl, but anything that gets the job done would be great.

4 Answers 4

This SO question covers this.

Assuming that the processes share a session identifier (which they should unless they’ve explicitly called setsid(), you can kill them by session using pkill:

If from another terminal I do:

Then everything dies in one fell swoop.

You can similarly kill by process group, though this tends to be more useful for many children that are all one level below a parent, not a chain of associated processes.

Usually, a responding client should receive a sigterm and off itself, thereby terminating all its forked child processes. If, on the other hand, the client is not responding, a normal termination signal will probably evoke no response.

So you then proceed to send a SIGKILL, which tells the system itself to Make That Process Stop, Now — which it can do most of the times, except when the process is in a state of ininterruptible sleep, like waiting for some I/O input or similar.

In that case, even the SIGKILL will end up doing nothing to the process; the child process will probably in a similar state of retardation.

There is a border case where the parent process might terminate just nicely, but the child process is not killable. Then you will end up with a zombie process that cannot be cleaned up since its father is gone, but it is not responding to anything. The only way to get rid of those is a reboot; in most cases, though, they are quite harmless, as the only thing they do is take up a PID while whatever socket they tried to use has withered away already.

Читайте также:  Как включить powerpoint windows 10

Источник

How to kill a child process after a given timeout in Bash?

I have a bash script that launches a child process that crashes (actually, hangs) from time to time and with no apparent reason (closed source, so there isn’t much I can do about it). As a result, I would like to be able to launch this process for a given amount of time, and kill it if it did not return successfully after a given amount of time.

Is there a simple and robust way to achieve that using bash?

P.S.: tell me if this question is better suited to serverfault or superuser.

9 Answers 9

If you don’t mind downloading something, use timeout ( sudo apt-get install timeout ) and use it like: (most Systems have it already installed otherwise use sudo apt-get install coreutils )

If you don’t want to download something, do what timeout does internally:

In case that you want to do a timeout for longer bash code, use the second option as such:

or to get the exit codes as well:

I also had this question and found two more things very useful:

  1. The SECONDS variable in bash.
  2. The command «pgrep».

So I use something like this on the command line (OSX 10.9):

As this is a loop I included a «sleep 0.2» to keep the CPU cool. 😉

(BTW: ping is a bad example anyway, you just would use the built-in «-t» (timeout) option.)

Assuming you have (or can easily make) a pid file for tracking the child’s pid, you could then create a script that checks the modtime of the pid file and kills/respawns the process as needed. Then just put the script in crontab to run at approximately the period you need.

Let me know if you need more details. If that doesn’t sound like it’d suit your needs, what about upstart?

One way is to run the program in a subshell, and communicate with the subshell through a named pipe with the read command. This way you can check the exit status of the process being run and communicate this back through the pipe.

Here’s an example of timing out the yes command after 3 seconds. It gets the PID of the process using pgrep (possibly only works on Linux). There is also some problem with using a pipe in that a process opening a pipe for read will hang until it is also opened for write, and vice versa. So to prevent the read command hanging, I’ve «wedged» open the pipe for read with a background subshell. (Another way to prevent a freeze to open the pipe read-write, i.e. read -t 5 <>finished.pipe — however, that also may not work except with Linux.)

Here’s an attempt which tries to avoid killing a process after it has already exited, which reduces the chance of killing another process with the same process ID (although it’s probably impossible to avoid this kind of error completely).

Use like run_with_timeout 3 sleep 10000 , which runs sleep 10000 but ends it after 3 seconds.

This is like other answers which use a background timeout process to kill the child process after a delay. I think this is almost the same as Dan’s extended answer (https://stackoverflow.com/a/5161274/1351983), except the timeout shell will not be killed if it has already ended.

After this program has ended, there will still be a few lingering «sleep» processes running, but they should be harmless.

This may be a better solution than my other answer because it does not use the non-portable shell feature read -t and does not use pgrep .

Источник

Оцените статью