使用JSch进行脚本上传操作需要注意的地方

       之前做的项目中有一个远程执行脚本的需求,我之前使用的是直接用JSch远程执行命令来echo脚本内容,

果然这几天出现了问题,问题是啥就不赘述了,最后决定使用jsch的sftp方式来进行脚本上传的操作,一开始

遇到各种问题,先是session is down我去网上查了一会资料,发现这篇文章写得不错,有遇到同样问题的可

以看一下CentOS下 配置 sftp,解决问题后又遇到了一个新的问题就是session虽然连接上了,但是在复制文件

的时候总是报2:file is not find,我试着吧目标文件的地址从/root/execshell.sh改成了./execshell之后果然好

了,下面附上我的工具代码:

import com.jcraft.jsch.*;

import java.io.InputStream;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;

public class JSchSshCLient {
    private static final String CLASS_NAME = JSchSshCLient.class.getName();
    private static final Logger LOG = LoggerFactory.getLogger(JSchSshCLient.CLASS_NAME);
    private static final int DEFAULT_SESSION_TIMEOUT = 30000;
    private static final int DEFAULT_CHANNEL_TIMEOUT = 30000;
    private static final int DEFAULT_RESPONSE_BUFFER_SIZE = 1024;
    private static final String CHANNEL_TYPE = "exec";
    private Session session;

    public JSchSshCLient(final String ip, final int port, final String username, final String password) throws JSchSshException{
        JSchSshCLient.LOG.info("JSchSshCLient initialization: ip(" + ip + "), username(" + username + "), password(" + password + ")");
        try {
            final JSch jsch = new JSch();
            if (JSchSshCLient.LOG.isDebugEnabled()) {
                JSchSshCLient.LOG.debug("Trying to establish ssh connection with " + username + "@" + ip + ", password=" + password);
            }
            (this.session = jsch.getSession(username, ip, port)).setPassword(password);
            this.session.setUserInfo(new MyUserInfo() {
                @Override
                public String getPassword() {
                    return password;
                }
            });
            this.session.setConfig("StrictHostKeyChecking", "no");
            this.session.connect(DEFAULT_SESSION_TIMEOUT);
        } catch (Exception e) {
            JSchSshCLient.LOG.error("JSchSshCLient init error for ip " + ip + ", message is " + e.getMessage());
            throw new JSchSshException("[JSchSshCLient] JSchSshCLient initialization error: init client failed, message:" + e.getMessage());
        }
    }

    public JSchSshCLient(final String ip, final int port, final String username,
                         final String password,final String filePath) throws JSchSshException{
        JSchSshCLient.LOG.info("JSchSshCLient initialization: ip(" + ip + "), username(" + username + "), " +
                "filePath("+filePath+").password(" + password + ")");
        try {
            final JSch jsch = new JSch();
            if (JSchSshCLient.LOG.isDebugEnabled()) {
                JSchSshCLient.LOG.debug("Trying to establish ssh connection with " + username + "@" + ip
                        + ", privatePair="+filePath+"password=" + password);
            }
            jsch.addIdentity(filePath,password);
            this.session=jsch.getSession(username, ip, port);
            this.session.setUserInfo(new MyUserInfo() {
                @Override
                public String getPassword() {
                    return password;
                }
            });
            this.session.setConfig("StrictHostKeyChecking", "no");
            this.session.connect(DEFAULT_SESSION_TIMEOUT);
        } catch (Exception e) {
            JSchSshCLient.LOG.error("JSchSshCLient init error for ip " + ip + ", message is " + e.getMessage());
            throw new JSchSshException("[JSchSshCLient] JSchSshCLient initialization error: init client failed, message:" + e.getMessage());
        }
    }

    public void close() {
        this.session.disconnect();
    }

    public String runCommand(final String command) throws JSchSshException{
        Channel channel = null;
        try {
            channel = this.session.openChannel(CHANNEL_TYPE);
            ((ChannelExec) channel).setCommand(command);
            ((ChannelExec) channel).setErrStream(System.err);
            final InputStream inStream = channel.getInputStream();
            channel.connect(DEFAULT_CHANNEL_TIMEOUT);
            final StringBuilder result = new StringBuilder();
            final byte[] buffer = new byte[DEFAULT_RESPONSE_BUFFER_SIZE];
            while (true) {
                if (inStream.available() > 0) {
                    final int i = inStream.read(buffer, 0, 1024);
                    if (i >= 0) {
                        result.append(new String(buffer, 0, i));
                        continue;
                    }
                }
                if (channel.isClosed()) {
                    break;
                }
                try {
                    Thread.sleep(1000L);
                } catch (Exception e) {
                    JSchSshCLient.LOG.error("Sleep error: ", e);
                }
            }
            JSchSshCLient.LOG.info("Command exit status: " + channel.getExitStatus());
            inStream.close();
            return result.toString();
        } catch (Exception e2) {
            JSchSshCLient.LOG.error(JSchSshCLient.CLASS_NAME, "runCommand", e2);
            throw new JSchSshException(e2);
        } finally {
            if (channel != null) {
                channel.disconnect();
            }
        }
    }

    public SshCommandResultVo runCommandWithExitStatus(final String command) {
        Channel channel = null;
        SshCommandResultVo resultVo = new SshCommandResultVo();
        try {
            channel = this.session.openChannel(CHANNEL_TYPE);
            ((ChannelExec) channel).setCommand(command);
            ((ChannelExec) channel).setErrStream(System.err);
            final InputStream inStream = channel.getInputStream();
            LOG.info(Thread.currentThread().getName() + " channel.connect...");
            channel.connect(DEFAULT_CHANNEL_TIMEOUT);
            final StringBuilder result = new StringBuilder();
            final byte[] buffer = new byte[DEFAULT_RESPONSE_BUFFER_SIZE];
            while (true) {
                if (inStream.available() > 0) {
                    final int i = inStream.read(buffer, 0, 1024);
                    if (i >= 0) {
                        result.append(new String(buffer, 0, i));
                        continue;
                    }
                }
                if (channel.isClosed()) {
                    break;
                }
                try {
                    Thread.sleep(1000L);
                } catch (Exception e) {
                    JSchSshCLient.LOG.error("Sleep error: ", e);
                }
            }
            inStream.close();
            JSchSshCLient.LOG.info("Command exit status: " + channel.getExitStatus());
            resultVo.setExitStatus(channel.getExitStatus());
            resultVo.setOutput(result.toString());
        } catch (Exception e2) {
            JSchSshCLient.LOG.error(Thread.currentThread().getName() + " runCommandWithExitStatus error, " + e2.toString());
            resultVo.setException(e2);
        } finally {
            if (channel != null) {
                JSchSshCLient.LOG.info("invoke channel.disconnect...");
                channel.disconnect();
            }
        }
        if(null == resultVo.getException()) {
            JSchSshCLient.LOG.info("run command success...");
        } else {
            JSchSshCLient.LOG.info("run command failed...");
        }
        return resultVo;
    }

    public void uploadFild(String sourcePath,String targetPath) throws SftpException, JSchException {
        ChannelSftp sftpChannel = null;
        try {
            sftpChannel = (ChannelSftp) session.openChannel("sftp");
            sftpChannel.connect();

            sftpChannel.put(sourcePath,targetPath);
        }
        finally {
            if(sftpChannel != null){
                sftpChannel.disconnect();
            }
        }
    }

    public abstract static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
        @Override
        public abstract String getPassword();
        @Override
        public boolean promptYesNo(final String str) {
            return false;
        }
        @Override
        public String getPassphrase() {
            return null;
        }
        @Override
        public boolean promptPassphrase(final String message) {
            return false;
        }
        @Override
        public boolean promptPassword(final String message) {
            return false;
        }
        @Override
        public void showMessage(final String message) {
        }
        @Override
        public String[] promptKeyboardInteractive(final String destination, final String name, final String instruction, final String[] prompt, final boolean[] echo) {
            return null;
        }
    }
}

你可能感兴趣的:(爬坑收获)