以前寫過一篇:《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
能夠進行設置 ,進行代碼測試: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()進行延遲。