java使用ssh鏈接AIX系統執行命令

以前寫過一篇:《JAVA經過SSH方式修改AIX用戶密碼》html

經過ganymed-ssh2-build210.jar這個工具鏈接ssh,其沒法執行passwd,緣由在於經過該jar創建的鏈接,沒有僞終端。java

發送的ssh鏈接命令是:ssh username@ip command;git

而能夠在終端經過ssh -t username@ip command 能夠正常執行;github

man ssh; 有這樣的鏈接參數;shell

 -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建立鏈接的時候指定能夠使用僞終端;api

查看jar中的Connection 及 Session沒有對該項的設置;須要考慮使用其餘的工具:jschsession

查看jsch channelExec api:app

setPty(boolean bool)ssh

能夠進行設置 ,進行代碼測試:ide

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()進行延遲。

相關文章
相關標籤/搜索