美文网首页自动化测试
java实现ssh登录linux服务器并下发命令

java实现ssh登录linux服务器并下发命令

作者: 测试你个头 | 来源:发表于2017-01-23 15:12 被阅读498次

    背景:需要开发一个小工具,实现ssh登录linux服务器采集cpu利用率、内存利用率等等监控功能

    基于jsch开发,jsch是一个ssh2的纯java实现,client代码参考了jsch的大量examples

    不多说话,先上code:

    实现关键的3个接口:login/logout/sendCmd,分别是登录、登出、下发命令

    import com.jcraft.jsch.*;
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * SSHClient based on jsch
     * examples: com.wow.remoteutils.SSHClientTest
     *
     * Created by kisrosen on 17/1/22.
     */
    @Component
    public class SSHClient {
    
        /**
         * Server Host IP Address,default value is localhost
         */
        private String host = "localhost";
    
        /**
         * Server SSH Port,default value is 22
         */
        private Integer port = 22;
    
        /**
         * SSH Login Username
         */
        private String username = "";
    
        /**
         * SSH Login Password
         */
        private String password = "";
    
        /**
         * JSch
         */
        private JSch jsch = null;
    
        /**
         * ssh session
         */
        private Session session = null;
    
        /**
         * ssh channel
         */
        private Channel channel = null;
    
        /**
         * timeout for session connection
         */
        private final Integer SESSION_TIMEOUT = 30000;
    
        /**
         * timeout for channel connection
         */
        private final Integer CHANNEL_TIMEOUT = 30000;
    
        /**
         * the interval for acquiring ret
         */
        private final Integer CYCLE_TIME = 100;
    
        public SSHClient() {
            // initialize
            jsch = new JSch();
        }
    
        public SSHClient setHost(String host) {
            this.host = host;
            return this;
        }
    
        public SSHClient setPort(Integer port) {
            this.port = port;
            return this;
        }
    
        public SSHClient setUsername(String username) {
            this.username = username;
            return this;
        }
    
        public SSHClient setPassword(String password) {
            this.password = password;
            return this;
        }
    
    
        /**
         * login to server
         *
         * @param username
         * @param password
         */
        public void login(String username, String password) {
    
            this.username = username;
            this.password = password;
    
            try {
                if (null == session) {
    
                    session = jsch.getSession(this.username, this.host, this.port);
                    session.setPassword(this.password);
                    session.setUserInfo(new MyUserInfo());
    
                    // It must not be recommended, but if you want to skip host-key check,
                    // invoke following,
                    session.setConfig("StrictHostKeyChecking", "no");
                }
    
                session.connect(SESSION_TIMEOUT);
            } catch (JSchException e) {
                System.err.println(e);
                this.logout();
            }
        }
    
        /**
         * login to server
         */
        public void login() {
            this.login(this.username, this.password);
        }
    
        /**
         * logout of server
         */
        public void logout() {
            this.session.disconnect();
        }
    
        /**
         * send command through the ssh session,return the ret of the channel
         *
         * @return
         */
        public String sendCmd(String command) {
    
            String ret = "";
    
            // judge whether the session or channel is connected
            if (!session.isConnected()) {
                this.login();
            }
    
            // open channel for sending command
            try {
                this.channel = session.openChannel("exec");
                ((ChannelExec) this.channel).setCommand(command);
                this.channel.connect(CHANNEL_TIMEOUT);
    
                // no output stream
                channel.setInputStream(null);
    
                ((ChannelExec) channel).setErrStream(System.err);
    
                InputStream in = channel.getInputStream();
    
                // acquire for ret
                byte[] tmp = new byte[1024];
                while (true) {
                    while (in.available() > 0) {
                        int i = in.read(tmp, 0, 1024);
                        if (i < 0) break;
    
                        ret = new String(tmp, 0, i);
                        System.out.print(ret);
                    }
    
                    // quit the process of waiting for ret
                    if (channel.isClosed()) {
                        if (in.available() > 0) continue;
                        System.out.println("exit-status: " + channel.getExitStatus());
                        break;
                    }
    
                    // wait every 100ms
                    try {
                        Thread.sleep(CYCLE_TIME);
                    } catch (Exception ee) {
                        System.err.println(ee);
                    }
                }
    
            } catch (JSchException e) {
                e.printStackTrace();
                System.err.println(e);
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println(e);
            } finally {
                // close channel
                this.channel.disconnect();
            }
    
            return ret;
        }
    
        /**
         * customized userinfo
         */
        private static class MyUserInfo implements UserInfo {
            @Override
            public String getPassphrase() {
                return null;
            }
    
            @Override
            public String getPassword() {
                return null;
            }
    
            @Override
            public boolean promptPassword(String s) {
                return false;
            }
    
            @Override
            public boolean promptPassphrase(String s) {
                return false;
            }
    
            @Override
            public boolean promptYesNo(String s) {
                return true;
            }
    
            @Override
            public void showMessage(String s) {
                System.out.println("showMessage:" + s);
            }
        }
    }
    

    调用代码:

    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    /**
     * Created by kisrosen on 17/1/23.
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:CommonUtils.xml")
    public class SSHClientTest {
    
        @Autowired
        private SSHClient sshClient;
    
        @Before
        public void setUp() throws Exception {
            sshClient.setHost("localhost").setPort(10022).setUsername("root").setPassword("root");
            sshClient.login();
        }
    
        @Test
        public void sendCmd() throws Exception {
            String ret = sshClient.sendCmd("pwd");
    
            System.out.println("******************************");
            System.out.println(ret);
            System.out.println("******************************");
    
            Assert.assertNotNull(ret);
            Assert.assertTrue(ret.length() > 0);
    
            ret = sshClient.sendCmd("vmstat");
    
            System.out.println("******************************");
            System.out.println(ret);
            System.out.println("******************************");
    
            Assert.assertNotNull(ret);
            Assert.assertTrue(ret.length() > 0);
        }
    
        @After
        public void tearDown() throws Exception {
            sshClient.logout();
        }
    }
    

    执行结果:


    可以使用正则表达式匹配一些关键信息实现采集

    相关文章

      网友评论

        本文标题:java实现ssh登录linux服务器并下发命令

        本文链接:https://www.haomeiwen.com/subject/wuyabttx.html