您的位置:首页 > 运维架构 > Shell

Java调用 shell脚本阻塞

2015-06-11 08:36 555 查看
Java在调用Shell时,要不断读取进程中标准输出和错误输出流的信息,否则缓冲区被写满就会造成子进程阻塞而无法继续运行下去,可起两个线程不断读取标准输出、错误流信息而不被阻塞
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.commons.io.IOUtils;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;

public class RmtShellExecutor {

private Connection conn;
private String ip;
private String usr;
private String psword;
private String charset = Charset.defaultCharset().toString();

private static final int TIME_OUT = 1000 * 5 * 60;

public RmtShellExecutor(String ip, String usr, String ps) {
this.ip = ip;
this.usr = usr;
this.psword = ps;
}

private boolean login() throws IOException {
conn = new Connection(ip);
conn.connect();
return conn.authenticateWithPassword(usr, psword);
}

//本地执行方法
public static void execLocal(String cmd) {
try {
Process proc = Runtime.getRuntime().exec(cmd);
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
errorGobbler.start();
outputGobbler.start();
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Exception e) {
e.printStackTrace();
}

}

//远程执行方法
public int execRemote(String cmds){
InputStream stdOut = null;
InputStream stdErr = null;
int ret = -1;
try {
if (login()) {
// Open a new {@link Session} on this connection
Session session = conn.openSession();
// Execute a command on the remote machine.
session.execCommand(cmds);

GobblerThread gtOut = new GobblerThread(session.getStdout(),"STD_OUT");
GobblerThread gtErr = new GobblerThread(session.getStderr(),"STD_ERR");
gtOut.start();
gtErr.start();

session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
ret = session.getExitStatus();
} else {
}
}catch(Exception e){
e.printStackTrace();
}
finally {
if (conn != null) {
conn.close();
}
IOUtils.closeQuietly(stdOut);
IOUtils.closeQuietly(stdErr);
}
return ret;
}

public static void main(String args[]) throws Exception {
RmtShellExecutor exe = new RmtShellExecutor("192.168.3.5", "test",
"123456");
System.out.println(exe.execRemote("sh /home/test/cmd.sh company=32"));
}
}

class GobblerThread extends Thread
{
InputStream is;
String type;

GobblerThread(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(line);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
execLocal 为本地调用cmd的方法

exeRemote 可利用ssh登录远程机器调用cmd的方法

参考文章:http://www.linuxidc.com/Linux/2014-04/99557.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java shell 阻塞 输出流