package com.corp.prj.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
/**
* Provides static methods for running SSH, scp as well as local commands. *
*/
public class CommandRunner {
private static final Logger logger = Logger.getLogger(CommandRunner.class); private CommandRunner() {
}
/**
* Get remote file through scp
* @param host
* @param username
* @param password
* @param remoteFile
* @param localDir
* @throws IOException
*/
public static void scpGet(String host, String username, String password, String remoteFile, String localDir) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("spc [" + remoteFile + "] from " + host + " to " + localDir);
}
Connection conn = getOpenedConnection(host, username, password);
SCPClient client = new SCPClient(conn);
client.get(remoteFile, localDir);
conn.close();
}
/**
* Put local file to remote machine.
* @param host
* @param username
* @param password
* @param localFile
* @param remoteDir
* @throws IOException
*/
public static void scpPut(String host, String username, String password,
String localFile, String remoteDir) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("spc [" + localFile + "] to " + host + remoteDir);
}
Connection conn = getOpenedConnection(host, username, password);
SCPClient client = new SCPClient(conn);
client.put(localFile, remoteDir);
conn.close();
}
/**
* Run SSH command.
* @param host
* @param username
* @param password
* @param cmd
* @return exit status
* @throws IOException
*/
public static int runSSH(String host, String username, String password,
String cmd) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("running SSH cmd [" + cmd + "]");
}
Connection conn = getOpenedConnection(host, username, password);
Session sess = conn.openSession();
sess.execCommand(cmd);
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
// attention: do not comment this block, or you will hit NullPointerException
// when you are trying to read exit status
String line = br.readLine();
if (line == null)
break;
if (logger.isDebugEnabled()) {
logger.debug(line);
}
}
sess.close();
conn.close();
return sess.getExitStatus().intValue();
/**
* return a opened Connection
* @param host
* @param username
* @param password
* @return
* @throws IOException
*/
private static Connection getOpenedConnection(String host, String username, String password) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("connecting to " + host + " with user " + username
+ " and pwd " + password);
}
Connection conn = new Connection(host);
conn.connect(); // make sure the connection is opened
boolean isAuthenticated = conn.authenticateWithPassword(username,
password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
return conn;
}
/**
* Run local command
* @param cmd
* @return exit status
* @throws IOException
*/
public static int runLocal(String cmd) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("running local cmd [" + cmd + "]");
}
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
InputStream stdout = new StreamGobbler(p.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
String line = br.readLine();
if (line == null)
break;
if (logger.isDebugEnabled()) {
logger.debug(line);
}
return p.exitValue();
}
}
public static String sshExecute(String host, String user, String pwd, String command) {
String osName = System.getProperty("https://www.doczj.com/doc/df14536485.html,");
// ps -ef|grep tomcat|grep -v grep|awk '{print $2}'
StringBuffer sb = new StringBuffer();
try {
JSch jsch = new JSch();
if (osName.toUpperCase().indexOf("WINDOWS") > -1) {
jsch.setKnownHosts("c:\\known_hosts");
} else {
jsch.setKnownHosts("/root/.ssh/known_hosts");
}
Session session = jsch.getSession(user, host, 22);
session.setPassword(pwd);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
InputStream in = channel.getInputStream();
channel.connect();
int nextChar;
while (true) {
while ((nextChar = in.read()) != -1) {
sb.append((char) nextChar);
}
if (channel.isClosed()) {
System.out.println("exit-status: "
+ channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 利用JSch包实现远程主机SHELL命令执行
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口,如果取默认值,传-1
* @param privateKey 密钥文件路径
* @param passphrase 密钥的密码
*/
public static void sshShell(String ip, String user, String psw
,int port ,String privateKey ,String passphrase) throws Exception{ Session session = null;
Channel channel = null;
JSch jsch = new JSch();
//设置密钥和密码
if (privateKey != null && !"".equals(privateKey)) {
if (passphrase != null && "".equals(passphrase)) {
//设置带口令的密钥
jsch.addIdentity(privateKey, passphrase);
} else {
//设置不带口令的密钥
jsch.addIdentity(privateKey);
}
}
if(port <=0){
//连接服务器,采用默认端口
session = jsch.getSession(user, ip);
}else{
//采用指定的端口连接服务器
session = jsch.getSession(user, ip ,port);
}
//如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
//设置登陆主机的密码
session.setPassword(psw);//设置密码
//设置第一次登陆的时候提示,可选值:(ask | yes | no) session.setConfig("StrictHostKeyChecking", "no");
//设置登陆超时时间
session.connect(30000);
try {
//创建sftp通信通道
channel = (Channel) session.openChannel("shell");
channel.connect(1000);
//获取输入流和输出流
InputStream instream = channel.getInputStream();
OutputStream outstream = channel.getOutputStream();
//发送需要执行的SHELL命令,需要用\n结尾,表示回车String shellCommand = "ls \n";
outstream.write(shellCommand.getBytes());
outstream.flush();
//获取命令执行的结果
if (instream.available() > 0) {
byte[] data = new byte[instream.available()];
int nLen = instream.read(data);
if (nLen < 0) {
throw new Exception("network error.");
}
//转换输出结果并打印出来
String temp = new String(data, 0, nLen,"iso8859-1");
System.out.println(temp);
}
outstream.close();
instream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.disconnect();
channel.disconnect();
}
}
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 https://www.doczj.com/doc/df14536485.html,erInfo;
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;
https://www.doczj.com/doc/df14536485.html,er=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
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
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
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) {
}
}
}