记录下通过Java命令来调用shell的方法,简单的记录下;在Java中有时候需要通过调用shell命令来完成对应的操作,之后返回执行的结果进行一些结果的解析,可以使用Runtime.getRuntime().exec()方法来执行shell命令,具体的方法如下:
public Process exec(String command) //在单独的进程中执行指定的字符串命令。
public Process exec(String [] cmdArray) //在单独的进程中执行指定命令和变量
1. RunTime.getRuntime().exec(String command)
相当于windows中开始中直接执行command命令;比如Runtime.getRuntime().exec("notepad.exe");则打开windows下记事本。
2.public Process exec(String [] cmdArray)
Linux下:Runtime.getRuntime().exec(new String[]{"/bin/sh","-c", cmds);
Windows下:Runtime.getRuntime().exec(new String[]{ "cmd", "/c", cmds});
3.Process的几个方法
public abstract OutputStream getOutputStream();
public abstract InputStream getInputStream();
public abstract InputStream getErrorStream();
public abstract int waitFor() throws InterruptedException;
public boolean waitFor(long timeout, TimeUnit unit)
public abstract int exitValue();
public abstract void destroy();
public boolean isAlive();
注意:waitFor方法会阻塞执行,导致当前线程一直等待;会一直等到process对象表示的进程终止才会返回;比如
@Test
public void testShell() throws IOException, InterruptedException {
Process p = null;
p = Runtime.getRuntime().exec(new String[]{"cmd", "/c", "notepad"});
p.waitFor();
System.out.println("--------------------------------------------我被执行了");
}
不关闭notepad,下面的输出语句不会打印出来;
4.process的阻塞
在runtime执行一些比较大的命令,输入流和输出流会不断存储在jvm的缓冲区中,如果不进行读取操作,当缓冲区被填满时,就会造成runtime的阻塞,比如进行大文件的复制操作等;所以需要启动另外的线程对流的结果进行读取,来防止runtime的阻塞问题;可以通过一个线程池去进行流的读取的任务,最后返回一个future对象;
process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", cmd});
future = POOL.submit(new ShellCallable(process));
private static class ShellCallable implements Callable<String> {
Process process;
ShellCallable(Process process) {
this.process = process;
}
@Override
public String call() throws Exception {
InputStream input = process.getInputStream();
String result = getResult(input);
if (result.equals("")) {
InputStream error = process.getErrorStream();
String errorInfo = getResult(error);
if (!errorInfo.equals("")) {
out.error(new RuntimeException(errorInfo));
}
}
return result;
}
private String getResult(InputStream input) throws Exception {
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[1024];
while (true) {
int len = input.read(buf);
if (len == -1) {
break;
}
sb.append(new String(buf, 0, len));
}
return sb.toString().trim();
}
}
参考文章: