用Java程序来控制shell脚本的运行和停止。具体来讲,这个Java程序至少要有三个功能:
- 运行Shell脚本;
- 等待Shell脚本执行结束;
- 停止运行中的Shell程序;
从功能需求来看,似乎是比较容易做到的。尽管没有写过类似功能的程序,Google一下,很快就有答案了。
用Runtime或者ProcessBuilder可以运行程序,而Process类的waitFor()和destroy()方法分别满足功能2和3。
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ShellRunner extends Thread
{
private Process proc;
private String dir;
private String shell;
public ShellRunner(String dir, String shell)
{
super();
this.proc = null;
this.dir = dir;
this.shell = shell;
}
@Override
public void run() {
try
{
ProcessBuilder builder = new ProcessBuilder("sh", dir + shell);
builder.directory(new File(dir));
proc = builder.start();
System.out.println("Running ...");
int exitValue = proc.waitFor();
System.out.println("Exit Value: " + exitValue);
}
catch (IOException e)
{
e.getLocalizedMessage();
}
catch (InterruptedException e)
{
e.getLocalizedMessage();
}
}
public void kill()
{
if (this.getState() != State.TERMINATED) {
proc.destroy();
}
}
public static void main(String args[]) {
ShellRunner runner = new ShellRunner("/tmp/", "run.sh");
runner.start();
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(inputStreamReader);
try
{
String line = null;
while ( (line = reader.readLine()) != null ) {
if (line.equals("kill")) {
runner.kill();
}
else if (line.equals("break")) {
break;
}
else {
System.out.println(runner.getState());
}
}
reader.close();
inputStreamReader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
waitFor()方法可以正确等待shell程序退出,但是destroy()方法并没有结束shell脚本相关的进程。
这是一个BUG。
JDK-bug-4770092:Process.destroy()不能结束孙子进程(grandchildren)。