標籤:java shell 阻塞 輸出資料流
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 connectionSession 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
Java調用 shell指令碼阻塞