java远程调用ssh2执行Linux命令

java SSH2远程登录Linux服务执行命令

前一段时间工作中用到了java远程调用Linux服务器,执行相关命令,因为比较常用,故此,在博客中记录下来。其中用到了ganymed-ssh2这个jar包,可以在http://www.ganymed.ethz.ch/ssh2/找到相关jar,不过这个jar目前好像已经停止维护了,还有一点是,这个jar,我在阿里的maven仓库中未找到。
好了,下面我们来贴下代码

/**
 * 
 */
package com.neusoft.mid.cloong.web.page.inspect.ssh;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;

import com.neusoft.mid.iamp.logger.LogService;

public class SSHConnect {

    private static LogService log = LogService.getLogger(SSHConnect.class);

    private static final int TIMEOUT = 2000;

    private static final int RECONNECT_TIMES = 20;

    private String userName;

    private String host;

    private String pass;

    private int port;

    private int sleepTime;

    private int waitTime;

    public Session openConnection() throws Exception {

        Connection connection = connect(host, port, TIMEOUT);
        if (!connection.authenticateWithPassword(userName, pass)) {
            throw new Exception("用户名密码错误");
        }
        log.info("登陆成功!");
        Session session = connection.openSession();
        session.requestPTY("");
        session.startShell();
        return session;
    }

    private Connection connect(String address, int port, long timeOut) {

        Connection conn = new Connection(address, port);
        int connectTimes = 1;
        long waitTime = System.currentTimeMillis() + timeOut;
        do {
            try {
                conn.connect();
                break;
            } catch (IOException e) {
                log.error(null, "ssh连接到主机时出错", e);
                connectTimes++;
            }
        } while (System.currentTimeMillis() < waitTime
                && RECONNECT_TIMES <= connectTimes);
        return conn;
    }

    public InputStream executeCommand(String command, Session session)
            throws Exception {

        if (command.equals("")) {
            log.info("执行空指令");
            return null;
        }
        PrintWriter out = null;
        try {
            out = new PrintWriter(new OutputStreamWriter(session.getStdin(),
                    "UTF-8"));
            out.println(command);
            out.flush();
            return handleBufferStr(session);
        } finally {
            if (null != out) {
                out.close();
            }
        }
    }

    /**
     * 处理接收的缓存数据
     */
    protected InputStream handleBufferStr(Session session) throws Exception {
        ByteArrayOutputStream sb = new ByteArrayOutputStream();
        ByteArrayOutputStream ersb = new ByteArrayOutputStream();
        InputStream in = null;
        try {
            if (sleepTime == 0) {
                return null;
            }
            Thread.sleep(sleepTime);
            in = receiveMsg(sb, ersb, session);
            return in;
        } finally {
            if (null != in) {
                in.close();
            }
        }
    }

    /**
     * 接收shell返回信息
     * 
     * @param stdNormal
     * @param stdError
     * @return
     * @throws Exception
     */
    protected InputStream receiveMsg(ByteArrayOutputStream stdNormal,
            ByteArrayOutputStream stdError, Session session) throws Exception {
        InputStream stdout = null;
        try {
            stdout = session.getStdout();
            // InputStream stderr = session.getStderr();
            int conditions = session.waitForCondition(
                    ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA
                            | ChannelCondition.EOF, waitTime);

            if ((conditions & ChannelCondition.TIMEOUT) != 0) {
                log.error(null, "获取session数据超时");
                throw new IOException("获取打印数据超时");
            }
            if ((conditions & ChannelCondition.EOF) != 0) {
                log.error(null, "无数据可读");
            }

            while (stdout.available() > 0) {
                return stdout;
                /*
                 * byte[] buffer = new byte[8192]; int len =
                 * stdout.read(buffer); if (len > 0) { // this check is somewhat
                 * paranoid if (log.isDebugEnable()) { //
                 * log.debug("Receive msg :" + buffer); }
                 * stdNormal.write(buffer, 0, len); }
                 */
            }

            /*
             * while (stderr.available() > 0) { byte[] buffer = new byte[8192];
             * int len = stderr.read(buffer); if (len > 0) {// this check is
             * somewhat paranoid if (log.isDebugEnable()) { //
             * log.debug("Receive error msg :" + buffer); }
             * stdError.write(buffer, 0, len); } }
             */
        } finally {
            if (null != stdout) {
                stdout.close();
            }
        }
        return null;
    }
}

代码框架比较老,用的是struts,我把get/set相关删掉了,main方法懒得写了,其中先调用openConnection方法,然后调用executeCommand方法就可以获得相关返回结果。
特别要注意的是Thread.sleep(sleepTime);这行代码。这行代码让线程睡一段时间是为了等待Linux返回结果,如果不睡,或者睡的时间比较短,会出现无法获取结果,或结果获取不全的情况。具体时间可以去Linux执行相关命令计算需要睡的时间。

总结

其中这个jar还可以实现端口转发,反向代理,等相关功能,等后续再继续添加吧。另外,相关实现ssh2相关功能的jar还有很多,比如jsch等,大家有空可以研究学习下,后续可以一起交流下经验。

你可能感兴趣的:(linux,java,ssh2)