六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 27|回复: 0

JAVA调用Shell脚本--及阻塞的解决办法

[复制链接]

升级  50.67%

32

主题

32

主题

32

主题

秀才

Rank: 2

积分
126
 楼主| 发表于 2013-1-26 14:02:54 | 显示全部楼层 |阅读模式
用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();          }    }}  
 
 
 
 
参考文章:
 

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
 
 
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表