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
本文出自 “脚踏实地,仰望星空” 博客,请务必保留此出处http://xubcing.blog.51cto.com/3502962/1660692
原文地址:http://xubcing.blog.51cto.com/3502962/1660692