這幾天項目中要把原來用FTP與TELNET兼容SSH協議,使用com.jcraft.jsch包,也差不多改完,把遇到的問題總結如下:
第一個就是登陸不上,返回異常:auth fail,一開始就登陸不上,鬱悶死啦。
不過最後還是在百度找到答案,解決如下:
修改配置文件sshd_config,將PasswordAuthentication設置爲 yes (是否需要密碼驗證)
然後重啓。
然後是要修改unix的IP 地址,發送了修改命令後,就沒反應了。不過還好第二天反應過來,IP改變後連接就斷開了吧,開始寫的程序是要獲得返回信息的,一直在等待對方返回。後來就直接發送命令就不管了,然後用修改的新IP連接上去,獲得IP,然後比較一個看是否修改了。來個簡化的:
/**
* 只發送執行命令不需要返回結果
*
* 修改IP時使用,修改後連接斷開,不能正常獲得返回信息.
* @param command
* @throws Exception
*/
public void sendCmd(String command) throws Exception
{
Channel channel = session.openChannel("exec");
ssh = (ChannelExec) channel;
ssh.setCommand(command);
ssh.connect();
//當然後面得關閉
}
然後再連接上去,獲得IP比較云云。
執行shell命令,當然還要獲得返回信息的。。。修改IP是執行SFTP上傳上去的腳本,自己寫的,然後執行完了會echo 返回信息,這沒問題,後來要查對方的JDK版本號,直接調unix上的java -version,卻什麼也不返回了。
還是百度,說是返回的信息可能是標準輸出,也有可能是錯誤輸出。所以就不能只獲得一個輸出流了,要這樣:
InputStream InputStream = ssh.getInputStream();
InputStream ErrStream = ssh.getErrStream();
網上我看來還有ssh.getStdout(),但我的怎麼就沒看到~~
來一個簡單版本吧:
* 執行命令,返回執行結果
* @param command 命令
* @return String 執行命令後的返回
* @throws IOException
* @throws JSchException
*/
public String sendCmd(String command)
throws Exception
{
byte[] tmp = new byte[1024]; //讀數據緩存
StringBuffer strBuffer = new StringBuffer(); //執行SSH返回的結果
Channel channel = session.openChannel("exec");
ssh = (ChannelExec) channel;
//返回的結果可能是標準信息,也可能是錯誤信息,所以兩種輸出都要獲取
//一般情況下只會有一種輸出.
//但並不是說錯誤信息就是執行命令出錯的信息,如獲得遠程java JDK版本就以
//ErrStream來獲得.
InputStream InputStream = ssh.getInputStream();
InputStream ErrStream = ssh.getErrStream();
ssh.setCommand(command);
ssh.connect();
//開始獲得SSH命令的結果
while(true)
{
//獲得錯誤輸出
while(ErrStream.available() > 0)
{
int i = ErrStream.read(tmp, 0, 1024);
if(i < 0)
{
break;
}
strBuffer.append(new String(tmp, 0, i));
}
//獲得標準輸出
while(InputStream.available() > 0)
{
int i = InputStream.read(tmp, 0, 1024);
if(i < 0)
{
break;
}
strBuffer.append(new String(tmp, 0, i));
}
if(ssh.isClosed())
{
logger.info("exit-status: " + ssh.getExitStatus());
break;
}
try
{
Thread.sleep(100);
}
catch(Exception ee)
{
}
}
return strBuffer.toString();
}
然後對返回信息進行處理云云。
基本就這幾個問題,其它都很順利。