2015-04-21 83 views
0

我按照下面的步驟在ssh服務器上運行命令。Shell命令沒有在java中使用jsch和expcetit庫運行

  1. 連接到SSH服務器
  2. 使用devpush命令重新登錄到服務器(使用用戶輸入提示expectit庫)。
  3. 最後使用jsch庫運行遠程命令。

我面臨的問題是,我的代碼進入無限循環,它能夠登錄到ssh服務器但無法運行命令。 任何人都可以幫助我,因爲我第一次使用這兩個庫。

package com.dmotorworks.cdk; 

import java.io.BufferedReader; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import net.sf.expectit.*; 
import net.sf.expectit.matcher.Matchers; 
import com.jcraft.jsch.Channel; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.JSchException; 
import com.jcraft.jsch.Session; 

public class ShellClient { 

    public void loginToPabloServer() throws IOException, JSchException{ 
     String hostname="pablo.dmotorworks.com"; 
     String username="gaikwasu"; 
     String password="[email protected]"; 
     final String endLineStr=" # "; 

     JSch jsch = new JSch();  
     Session session = jsch.getSession(username, hostname, 22); 
     session.setPassword(password); 
     jsch.setKnownHosts("C://Users//gaikwasu//.ssh//known_hosts"); 

     session.connect(); 
     System.out.println("Connected"); 


     Channel channel=session.openChannel("shell"); 
     channel.connect(); 

     Expect expect=new ExpectBuilder() 
       .withOutput(channel.getOutputStream()) 
       .withInputs(channel.getInputStream(), channel.getExtInputStream()) 
       .withEchoOutput(System.out) 
       .withEchoInput(System.err) 
       .withExceptionOnFailure() 
       .build(); 

     expect.expect(Matchers.contains("-bash-4.1$"));  
     expect.send("devpush\n"); 
     expect.expect(Matchers.contains("[sudo] password for")); 
     expect.send(password+"\n"); 


     DataInputStream dataIn = new DataInputStream(channel.getInputStream()); 
     DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream()); 
     BufferedReader bufferReader= new BufferedReader(new InputStreamReader(dataIn)); 

     dataOut.writeBytes("cd custom\n"); 
     dataOut.writeBytes("ls -lrt\n"); 
     dataOut.flush(); 

     String line=bufferReader.readLine(); 
     while(!line.endsWith(endLineStr)) { 
       System.out.println(line); 
      } 

     channel.disconnect(); 
     session.disconnect(); 
     expect.close(); 


    } 

    public static void main(String[] args) { 
     ShellClient shellClient=new ShellClient(); 
     try { 
      shellClient.loginToPabloServer(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (JSchException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

回答

0

最有可能的不定式循環的原因是因爲期待實例在同一時間讀取一個單獨的線程輸入數據,而你試圖同一數據在主線程。

嘗試在讀取數據之前關閉Expect實例。它可能有幫助。

但是,我強烈建議在發送密碼後繼續使用Expect實例。 ExpectIt可以幫助從遠程命令輸出中提取信息。例如:

expect.sendLine(password); 
    expect.expect(Matchers.contains("-bash-4.1$")); 
    expect.sendLine("cd custom"); 
    expect.expect(Matchers.contains("-bash-4.1$")); 
    expect.sendLine("ls -lrt"); 
    // the lsResult variable should contain the result of the 'ls -l' command 
    String lsResult = expect.expect(Matchers.contains("-bash-4.1$")).getBefore(); 
    System.out.println(lsResult); 

請看看this的例子。

+0

請評論你的代碼。我們很容易理解。我如何獲得控制檯輸出? –

+0

'getBefore'方法在匹配之前返回控制檯輸出。 'lsResult'變量應該包含'ls -l'命令的結果, –

+0

謝謝阿列克謝。我很難實現'sudo -i'。我會開始一個新的問題。你能看看嗎? http://stackoverflow.com/questions/31477489/expectit-trouble-implementing-a-sudo-i –