eeijlar
eeijlar

Reputation: 1340

Process.destroy() is not killing children of Process

ProcessBuilder does not support bash redirects, so if I run the following:

import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.List;


public class Test {

public static void main(String args[]) {
 ProcessBuilder builder = new ProcessBuilder();
 String command = "ping 127.0.0.1 > console.log";
 builder.command("bash"  , "-c", command); 
 //builder.redirectOutput(Redirect.appendTo(new File ("console.log")));
 System.out.println("Builder: " + builder.command().toString());

try {
  Process p = builder.start();
      System.out.println("Sleeping for 20 seconds");
      Thread.sleep(20000);
      p.destroy(); 
} catch (Exception e) {
      System.out.println("An error happened here");
    }

}

}

p.destroy() only kills the parent bash -c process but not the child. Is there any way to kill the child also? ping will continue running after the destroy.

According to this post Java - Process.destroy() source code for Linux, it eventually calls kill down at the native c code level.

But even if I do this in Linux it doesn't work:

[john@dub-001948-VM01:~/tmp ]$ bash -c 'ping 127.0.0.1 > console.log' &
[1] 30914
[john@dub-001948-VM01:~/tmp ]$ ps
 PID TTY          TIME CMD
30536 pts/1    00:00:00 bash
30914 pts/1    00:00:00 bash
30915 pts/1    00:00:00 ping
30916 pts/1    00:00:00 ps
[john@dub-001948-VM01:~/tmp ]$ kill -9 30914
[john@dub-001948-VM01:~/tmp ]$ ps -ef | grep ping
john     30915     1  0 15:19 pts/1    00:00:00 ping 127.0.0.1
john     30919 30536  0 15:19 pts/1    00:00:00 grep ping
[1]+  Killed                  bash -c 'ping 127.0.0.1 > console.log'
[john@dub-001948-VM01:~/tmp ]$ 

ping is still running..

Upvotes: 0

Views: 1163

Answers (1)

eeijlar
eeijlar

Reputation: 1340

It looks like bash does a fork and exec to start the child process, so the child won't be killed. However, if you use ksh instead of bash, you will get a fork without the exec:

ksh -c ping 127.0.0.1 > console.log

Using the ksh, process.destroy() kills both the ksh and the child process

I don't know for certain though, the -c option in the man page for both ksh and bash look quite similar.

Upvotes: 1

Related Questions