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