用java调用shell,使用
Process p=Runtime.getRuntime().exec(String[] cmd);
Runtime.exec方法将产生一个本地的进程,并返回一个Process子类的实例,该实例可用于控制进程或取得进程的相关信息。
由于调用Runtime.exec方法所创建的子进程没有自己的终端或控制台,因此该子进程的标准IO(如stdin,stdou,stderr)都通过
p.getOutputStream(),
p.getInputStream(),
p.getErrorStream()
方法重定向给它的父进程了.用户需要用这些stream来向 子进程输入数据或获取子进程的输出。
例如:Runtime.getRuntime().exec("ls")
另外需要关心的是Runtime.getRuntime().exec()中产生停滞(阻塞,blocking)的问题?
这个是因为Runtime.getRuntime().exec()要自己去处理stdout和stderr的输出,
就是说,执行的结果不知道是现有错误输出(stderr),还是现有标准输出(stdout)。
你无法判断到底那个先输出,所以可能无法读取输出,而一直阻塞。
例如:你先处理标准输出(stdout),但是处理的结果是先有错误输出(stderr),
一直在等错误输出(stderr)被取走了,才到标准输出(stdout),这样就产生了阻塞。
解决办法:
用两个线程将标准输出(stdout)和错误输出(stderr)。
参考代码:
- import java.util.*;
- import java.io.*;
- class StreamGobbler extends Thread
- {
- InputStream is;
- String type;
- StreamGobbler(InputStream is, String type)
- {
- this.is = is;
- this.type = type;
- }
- public void run()
- {
- try
- {
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- String line=null;
- while ( (line = br.readLine()) != null)
- System.out.println(type + ">" + line);
- } catch (IOException ioe)
- {
- ioe.printStackTrace();
- }
- }
- }
- public class ExecRunner
- {
- public static void main(String args[])
- {
- if (args.length < 1)
- {
- System.out.println("USAGE: java GoodWindowsExec <cmd>");
- System.exit(1);
- }
- try
- {
- String osName = System.getProperty("os.name" );
- String[] cmd = new String[3];
- if( osName.equals( "Windows NT" ) )
- {
- cmd[0] = "cmd.exe" ;
- cmd[1] = "/C" ;
- cmd[2] = args[0];
- }
- else if( osName.equals( "Windows 95" ) )
- {
- cmd[0] = "command.com" ;
- cmd[1] = "/C" ;
- cmd[2] = args[0];
- } else {
- StringTokenizer st = new StringTokenizer(command, " ");
- cmd = new String[st.countTokens()];
- int token = 0;
- while (st.hasMoreTokens()) {
- String tokenString = st.nextToken();
- // System.out.println(tokenString);
- cmd[token++] = tokenString;
- }
- }
- Runtime rt = Runtime.getRuntime();
- System.out.println("Execing " + cmd[0] + " " + cmd[1]
- + " " + cmd[2]);
- Process proc = rt.exec(cmd);
- // any error message?
- StreamGobbler errorGobbler = new
- StreamGobbler(proc.getErrorStream(), "ERROR");
- // any output?
- StreamGobbler outputGobbler = new
- StreamGobbler(proc.getInputStream(), "OUTPUT");
- // kick them off
- errorGobbler.start();
- outputGobbler.start();
- // any error???
- int exitVal = proc.waitFor();
- System.out.println("ExitValue: " + exitVal);
- } catch (Throwable t)
- {
- t.printStackTrace();
- }
- }
- }