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

转自: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 ");

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值