JSch中執行command的兩種方式
阿新 • • 發佈:2019-01-11
準備目標登入主機資訊:
public class DestHost { private String host = ""; private String username = ""; private String password = ""; private int port = 22; private int timeout = 60 * 60 * 1000; public DestHost(String host, String username, String password){ this(host, username, password, 22, 60*60*1000); } public DestHost(String host, String username, String password, int timeout){ this(host, username, password, 22, timeout); } public DestHost(String host, String username, String password, int port, int timeout) { super(); this.host = host; this.username = username; this.password = password; this.port = port; this.timeout = timeout; } ... }
SSH工具類:
1.JSch 使用shell執行命令,有兩種方法:
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");//只能執行一條指令(也可執行符合指令)
一次性執行多條shell的方法:
1)每個命令之間用;隔開
說明:各命令的執行給果,不會影響其它命令的執行。換句話說,各個命令都會執行,但不保證每個命令都執行成功。
2)每個命令之間用&&隔開
說明:若前面的命令執行成功,才會去執行後面的命令。這樣可以保證所有的命令執行完畢後,執行過程都是成功的。
3)每個命令之間用||隔開
說明:||是或的意思,只有前面的命令執行失敗後才去執行下一條命令,直到執行成功一條命令為止。
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");//可執行多條指令 不過需要輸入輸出流
public class SSHUtils { private static final String ENCODING = "UTF-8"; public static Session getJSchSession(DestHost destHost) throws JSchException { JSch jsch = new JSch(); Session session = jsch.getSession(destHost.getUsername(), destHost.getHost(), destHost.getPort()); session.setPassword(destHost.getPassword()); session.setConfig("StrictHostKeyChecking", "no");//第一次訪問伺服器不用輸入yes session.setTimeout(destHost.getTimeout()); session.connect(); return session; } public static String execCommandByJSch(Session session, String command, String resultEncoding) throws IOException,JSchException{ //1.預設方式,執行單句命令 ChannelExec channelExec = (ChannelExec) session.openChannel("exec"); InputStream in = channelExec.getInputStream(); channelExec.setCommand(command); channelExec.setErrStream(System.err); channelExec.connect(); String result = IOUtils.toString(in, resultEncoding); channelExec.disconnect(); return result; }
下面就是使用“shell”方式進行的呼叫:
public static String execCommandByShell(Session session)throws IOException,JSchException{
String result = "";
//2.嘗試解決 遠端ssh只能執行一句命令的情況
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
InputStream inputStream = channelShell.getInputStream();//從遠端到達的資料 都能從這個流讀取到
channelShell.setPty(true);
channelShell.connect();
OutputStream outputStream = channelShell.getOutputStream();//寫入該流的資料 都將傳送到遠端端
//使用PrintWriter 就是為了使用println 這個方法
//好處就是不需要每次手動給字元加\n
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println("cd /opt/applog/MSISVCServer");
printWriter.println("ls");
printWriter.println("exit");//為了結束本次互動
printWriter.flush();//把緩衝區的資料強行輸出
/**
shell管道本身就是互動模式的。要想停止,有兩種方式:
一、人為的傳送一個exit命令,告訴程式本次互動結束
二、使用位元組流中的available方法,來獲取資料的總大小,然後迴圈去讀。
為了避免阻塞
*/
byte[] tmp = new byte[1024];
while(true){
while(inputStream.available() > 0){
int i = inputStream.read(tmp, 0, 1024);
if(i < 0) break;
String s = new String(tmp, 0, i);
if(s.indexOf("--More--") >= 0){
outputStream.write((" ").getBytes());
outputStream.flush();
}
System.out.println(s);
}
if(channelShell.isClosed()){
System.out.println("exit-status:"+channelShell.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception e){}
}
outputStream.close();
inputStream.close();
channelShell.disconnect();
session.disconnect();
System.out.println("DONE");
return result;
}