java使用ssh连接AIX系统执行命令

之前写过一篇:《JAVA通过SSH方式修改AIX用户密码》

通过ganymed-ssh2-build210.jar这个工具连接ssh,其无法执行passwd,原因在于通过该jar建立的连接,没有伪终端。

发送的ssh连接命令是:ssh username@ip command;

而可以在终端通过ssh -t username@ip command 可以正常执行;

man ssh; 有这样的连接参数;

 -t      Force pseudo-tty allocation.  This can be used to execute arbitrary screen-based pro‐
             grams on a remote machine, which can be very useful, e.g. when implementing menu ser‐
             vices.  Multiple -t options force tty allocation, even if ssh has no local tty.

所以需要在ssh创建连接的时候指定可以使用伪终端;

查看jar中的Connection 及 Session没有对该项的设置;需要考虑使用其他的工具:jsch

查看jsch channelExec api:

setPty(boolean bool)

可以进行设置 ,进行代码测试:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

/**
 * 远程执行AIX的shell script ssh -t user@ip command
 * 
 */
public class SSHRemoteAIXExecute extends RemoteExecute {

    private static final String CHANGE_LINE = "\r";
    private static final String PASSWD_CMD = "passwd";
    private Logger logger = LoggerFactory.getLogger(SSHRemoteAIXExecute.class);
    private Session session;
    private JSch jsch;

    public SSHRemoteAIXExecute(String ip, String username, String userPwd, int port) {
        this.setIp(ip);
        this.setPort(port);
        this.setUsername(username);
        this.userPwd = userPwd;
    }

    @Override
    public void setIp(String ip) {
        super.setIp(ip);
        closeConn();
    }

    @Override
    public void setPort(int port) {
        super.setPort(port);
        closeConn();
    }

    private void closeConn() {
        if (session != null && session.isConnected()) {
            session.disconnect();
            session = null;
        }
    }

    @Override
    public void setUsername(String userName) {
        super.setUsername(userName);
        closeConn();
    }

    /**
     * 远程登录unix的主机
     * 
     * @return 登录成功返回true,否则返回false
     */
    public Boolean login() throws Exception {
        jsch = new JSch();
        session = jsch.getSession(this.getUsername(), this.getIp(), this.getPort());
        session.setPassword(this.userPwd);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        return session.isConnected();
    }

    /**
     * @param cmd
     *            即将执行的命令
     * @return 命令执行完后返回的结果值
     */
    @Override
    public String execute(String cmd) throws Exception {
        StringBuffer sb = new StringBuffer();
        if (login()) {
            ChannelExec channel = (ChannelExec) session.openChannel(JSCH_EXEC);
            channel.setPty(true);
            channel.setCommand(cmd);
            channel.connect();
            InputStream in = channel.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName(DEFAULTCHART)));
            String buf = null;
            Thread.sleep(1000);
            while ((buf = reader.readLine()) != null) {
                sb.append(buf + CHANGE_LINE);
            }
            reader.close();
            channel.disconnect();
            closeConn();
        }
        return sb.toString();
    }

    public boolean setNewPassword(String newpassword) throws Exception {
        if (login()) {
            ChannelExec channel = (ChannelExec) session.openChannel(JSCH_EXEC);
            channel.setPty(true);
            channel.setCommand(PASSWD_CMD);
            channel.connect();
            OutputStream out = channel.getOutputStream();
            InputStream in = channel.getInputStream();
            byte[] buffer = new byte[2048];
            Thread.sleep(1000);
            int length = in.read(buffer);
            String rs = "", coldpassword = "", cnewpass = "";
            if (length > 0) {
                rs = new String(buffer, 0, length);
                if (rs.contains("Error")) {
                    logger.error("ERROR");
                    return false;
                }
                if (!rs.contains("password:")) {
                    Thread.sleep(1000);
                    length = in.read(buffer);
                    rs = new String(buffer, 0, length);
                }
                if (rs.contains("Old")) {
                    // (current) UNIX password:
                    coldpassword = userPwd + CHANGE_LINE;
                    out.write(coldpassword.getBytes());
                    out.flush();
                    Thread.sleep(1000);
                    length = in.read(buffer);
                    rs = new String(buffer, 0, length);
                }
                if (length > 0 && !rs.contains("time")) {
                    // root's New password:
                    cnewpass = newpassword + CHANGE_LINE;
                    out.write(cnewpass.getBytes());
                    out.flush();
                    Thread.sleep(1000);
                    length = in.read(buffer);
                    rs = new String(buffer, 0, length);
                }
                if (rs.contains("again:")) {
                    // Enter the new password again:
                    cnewpass = newpassword + CHANGE_LINE;
                    out.write(cnewpass.getBytes());
                    out.flush();
                    Thread.sleep(1000);
                    length = in.read(buffer);
                    rs = new String(buffer, 0, length);
                }
                if (!rs.contains("Error")) {
                    this.isSuccessfully = true;
                }else{
                    this.isSuccessfully = false;
                    this.errorMessage = rs;
                }
            }
            channel.disconnect();
            closeConn();
        }
        return this.isSuccessfully;
    }

    public static void main(String[] args) {
        String ip = "ip";
        String userName = "username";
        String userPwd = "password";
        String newpassword = "newpassword";



        int port = 22;
        SSHRemoteAIXExecute rlec = new SSHRemoteAIXExecute(ip, userName, userPwd, port);
        try {
            rlec.setNewPassword(newpassword);
            // rlec.execute("who");
            System.out.println(rlec.isSuccessfully);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rlec.closeConn();
        }

    }
}

注:在in.read(buffer)时,可能会发生阻塞及获取字符长度不全,需要通过Tread.sleep()进行延迟。


猜你喜欢

转载自blog.csdn.net/c1052981766/article/details/79989550
今日推荐