java通过ssh登陆执行linux命令

package com.flyingzl.ssh;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.oro.text.regex.MalformedPatternException;

import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;


import expect4j.Closure;
import expect4j.Expect4j;
import expect4j.ExpectState;
import expect4j.matches.EofMatch;
import expect4j.matches.Match;
import expect4j.matches.RegExpMatch;
import expect4j.matches.TimeoutMatch;

publicclass Shell {

privatestatic Logger log = Logger.getLogger(Shell.class);

private Session session;
private ChannelShell channel;
privatestatic Expect4j expect =null;
privatestaticfinallong defaultTimeOut =1000;
private StringBuffer buffer=new StringBuffer();

publicstaticfinalint COMMAND_EXECUTION_SUCCESS_OPCODE =-2;
publicstaticfinal String BACKSLASH_R ="\r";
publicstaticfinal String BACKSLASH_N ="\n";
publicstaticfinal String COLON_CHAR =":";
publicstatic String ENTER_CHARACTER = BACKSLASH_R;
publicstaticfinalint SSH_PORT =22;

//正则匹配,用于处理服务器返回的结果
publicstatic String[] linuxPromptRegEx =new String[] { "~]#", "~#", "#",
":~#", "/$", ">" };

publicstatic String[] errorMsg=new String[]{"could not acquire the config lock "};

//ssh服务器的ip地址
private String ip;
//ssh服务器的登入端口
privateint port;
//ssh服务器的登入用户名
private String user;
//ssh服务器的登入密码
private String password;

public Shell(String ip,int port,String user,String password) {
this.ip=ip;
this.port=port;
this.user=user;
this.password=password;
expect
= getExpect();
}

/**
* 关闭SSH远程连接
*/
publicvoid disconnect(){
if(channel!=null){
channel.disconnect();
}
if(session!=null){
session.disconnect();
}
}

/**
* 获取服务器返回的信息
*
@return 服务端的执行结果
*/
public String getResponse(){
return buffer.toString();
}

//获得Expect4j对象,该对用可以往SSH发送命令请求
private Expect4j getExpect() {
try {
log.debug(String.format(
"Start logging to %s@%s:%s",user,ip,port));
JSch jsch
=new JSch();
session
= jsch.getSession(user, ip, port);
session.setPassword(password);
Hashtable
<String, String> config =new Hashtable<String, String>();
config.put(
"StrictHostKeyChecking", "no");
session.setConfig(config);
localUserInfo ui
=new localUserInfo();
session.setUserInfo(ui);
session.connect();
channel
= (ChannelShell) session.openChannel("shell");
Expect4j expect
=new Expect4j(channel.getInputStream(), channel
.getOutputStream());
channel.connect();
log.debug(String.format(
"Logging to %s@%s:%s successfully!",user,ip,port));
return expect;
}
catch (Exception ex) {
log.error(
"Connect to "+ip+":"+port+"failed,please check your username and password!");
ex.printStackTrace();
}
returnnull;
}

/**
* 执行配置命令
*
@param commands 要执行的命令,为字符数组
*
@return 执行是否成功
*/
publicboolean executeCommands(String[] commands) {
//如果expect返回为0,说明登入没有成功
if(expect==null){
returnfalse;
}

log.debug(
"----------Running commands are listed as follows:----------");
for(String command:commands){
log.debug(command);
}
log.debug(
"----------End----------");

Closure closure
=new Closure() {
publicvoid run(ExpectState expectState) throws Exception {
buffer.append(expectState.getBuffer());
// buffer is string
// buffer for appending
// output of executed
// command
expectState.exp_continue();

}
};
List
<Match> lstPattern =new ArrayList<Match>();
String[] regEx
= linuxPromptRegEx;
if (regEx !=null&& regEx.length >0) {
synchronized (regEx) {
for (String regexElement : regEx) {// list of regx like, :>, />
// etc. it is possible
// command prompts of your
// remote machine
try {
RegExpMatch mat
=new RegExpMatch(regexElement, closure);
lstPattern.add(mat);
}
catch (MalformedPatternException e) {
returnfalse;
}
catch (Exception e) {
returnfalse;
}
}
lstPattern.add(
new EofMatch(new Closure() { // should cause
// entire page to be
// collected
publicvoid run(ExpectState state) {
}
}));
lstPattern.add(
new TimeoutMatch(defaultTimeOut, new Closure() {
publicvoid run(ExpectState state) {
}
}));
}
}
try {
boolean isSuccess =true;
for (String strCmd : commands){
isSuccess
= isSuccess(lstPattern, strCmd);
}
//防止最后一个命令执行不了
isSuccess =!checkResult(expect.expect(lstPattern));

//找不到错误信息标示成功
String response=buffer.toString().toLowerCase();
for(String msg:errorMsg){
if(response.indexOf(msg)>-1){
returnfalse;
}
}

return isSuccess;
}
catch (Exception ex) {
ex.printStackTrace();
returnfalse;
}
}

//检查执行是否成功
privateboolean isSuccess(List<Match> objPattern, String strCommandPattern) {
try {
boolean isFailed = checkResult(expect.expect(objPattern));
if (!isFailed) {
expect.send(strCommandPattern);
expect.send(
"\r");
returntrue;
}
returnfalse;
}
catch (MalformedPatternException ex) {
returnfalse;
}
catch (Exception ex) {
returnfalse;
}
}

//检查执行返回的状态
privateboolean checkResult(int intRetVal) {
if (intRetVal == COMMAND_EXECUTION_SUCCESS_OPCODE) {
returntrue;
}
returnfalse;
}

//登入SSH时的控制信息
//设置不提示输入密码、不显示登入信息等
publicstaticclass localUserInfo implements UserInfo {
String passwd;

public String getPassword() {
return passwd;
}

publicboolean promptYesNo(String str) {
returntrue;
}

public String getPassphrase() {
returnnull;
}

publicboolean promptPassphrase(String message) {
returntrue;
}

publicboolean promptPassword(String message) {
returntrue;
}

publicvoid showMessage(String message) {

}
}

}
原文地址:https://www.cnblogs.com/ylqmf/p/2567811.html