Let's Go!

用java调用shell脚本,及解决阻塞的办法

上一篇 / 下一篇  2011-05-16 14:18:22 / 个人分类:JAVA学习&编程相关

转自:http://tivan.iteye.com/blog/1045518

 

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 sName = 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 utputGobbler = 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();
          }
    }
}

 

 

 

参考文章

 

When Runtime.exec() won't

Navigate yourself around pitfalls related to the Runtime.exec() method

 

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4

 

 

 


TAG:

 

评分:0

我来说两句

Open Toolbar