2014-04-07 33 views
0

我試圖在未觸及它10年後重新學習Java。我想用我希望編寫的其他應用程序創建一個使用JSch的庫。我已經解決了關係,但現在我正在使用stdin和stdout。 我正在尋找一種方法,它接受String中的單個命令並返回一個ArrayList和結果。JSch外殼返回到StringArray

任何援助將是偉大的!

//This vars are in the class. 
private JSch _jsch; 
private Session _session; 
private Channel _channel; 

這裏是我的連接方法

public boolean Connect() throws JSchException 
{ 
    try { 
     _jsch = new JSch(); 
     _session = _jsch.getSession(_user, _hostname, _port);  
     _session.setPassword(_password); 
     _session.setConfig("StrictHostKeyChecking", "no"); 

     _channel = _session.openChannel("shell"); 

     //((ChannelShell)_channel).setPtyType("vt100"); 

     _channel.setInputStream(bais); 
     _channel.setOutputStream(baos); 
     _channel.connect(3000);      
    }//try to connect 
    catch (JSchException ex) 
    { 
     throw ex; 
    } 
    return true; 
} 

的目標是有一次我打開連接我可以給這個方法的命令,並在數組中返回結果。根據結果​​採取行動併發送更多命令。我不想每次關閉連接,因爲它們將建立在它之前的命令上。我不確定如何使用輸入和輸出流足以獲得我期待的結果。如果您可以協助填寫以下方法,我將不勝感激。

public List<String> ExecuteCommand (String command) { 
    //run command to existing connection 
    //Get returned lines to Array List and return the list 
} 

感謝

+0

你想採取一個多行字符串(命令)並創建一個行的ArrayList?就這樣? –

+0

非常。我只是不確定如何在這裏處理java中的流。我的目標是做到以下幾點。 列表 results = ExecuteCommand(「ps -ef」); 我知道ps -ef會返回很多行,所以我想把它放到數組或ArrayList中。 – vSteve

回答

0

下面是運行本地進程和創建回ArrayList充滿一行行從過程的輸出的一個例子。雖然這不完全是你想要的,但它應該給你一個想法。

public List<String> ExecuteCommand (String command) { 
    Runtime r = Runtime.getRuntime(); 
    Process p = r.exec(command); 
    p.waitFor(); 
    BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    String line = ""; 
    ArrayList<String> output = new ArrayList<String>(); 
    while ((line = b.readLine()) != null) { 
     output.add(line); 
    } 
    return output; 
} 
0

我創建了一個open source project (click to see)來實現遠程文件系統。這裏是最重要的代碼片段,它也支持sudo。在這個例子中,我將錯誤輸出重定向到標準輸出。 如果您不想要錯誤輸出,您可以將其刪除。在這個例子中,我使用StringWriter而不是List <String>。我鼓勵你使用它。

/** 
* Executes commands at target host. 
* @throws IOException Failed to capture a return code 
*/ 
public int exec(boolean sudo, String command, StringWriter output) throws IOException { 
    ChannelExec channel = null; 
    try { 
     channel = (ChannelExec) session.openChannel("exec"); 
     sudo = sudo && !username.equals("root"); 
     if (sudo) { 
      command = "sudo -S -p '' " + command; 
      channel.setPty(true); 
     } 
     channel.setCommand(command); 

     InputStream stdout = channel.getInputStream(); // The stream will be recycled automatically 
     InputStream stderr = channel.getErrStream(); // The stream will be recycled automatically 
     channel.connect(); 

     boolean passwordEntered = false; 
     if (sudo && !StringUtils.isEmpty(password)) { 
      OutputStream stdin = channel.getOutputStream(); 
      stdin.write(password.getBytes()); 
      stdin.write("\n".getBytes()); 
      IOUtils.closeQuietly(stdin); 
      passwordEntered = true; 
     } 

     String contents = readFully(stdout); 
     if (passwordEntered) { 
      contents = contents.substring(password.length()); 
     } 
     output.write(contents.trim()); 
     contents = readFully(stderr); 

     int retval = channel.getExitStatus(); 
     if (retval != 0) { 
      output.append(contents.trim()); 
     } 
     return retval; 
    } 
    catch (JSchException ex) { 
     throw new IOException(ex); 
    } 
    finally { 
     output.flush(); 
     if (channel != null) { 
      channel.disconnect(); 
     } 
    } 
} 

private static String readFully(InputStream input) throws IOException { 
    StringBuilder output = new StringBuilder(); 
    int bytesRead = input.read(); 
    while (bytesRead != -1) { 
     output.append((char) bytesRead); 
     bytesRead = input.read(); 
    } 
    return output.toString(); 
} 
0

這是我目前的解決方案。它可以使用一些流內容和清理,但它正在讓我找到我正在尋找的東西。

我不想把這個標記爲答案,但是我之前沒有發佈到這個網站,所以如果我做錯了,請原諒。這裏是新的連接方法

public boolean Connect() throws JSchException 
{ 
    try { 
     _jsch = new JSch(); 
     _session = _jsch.getSession(_user, _hostname, _port);  
     _session.setPassword(_password); 
     _session.setConfig("StrictHostKeyChecking", "no"); 

     _session.connect(); 
     _channel = _session.openChannel("shell"); 

     _channel.setInputStream(null); 

     _isInput = _channel.getInputStream(); 
     _isOutput = _channel.getOutputStream(); 

     _reader = new BufferedReader (new InputStreamReader(_isInput)); 
     _writer = new BufferedWriter (new OutputStreamWriter (_isOutput)); 

     _channel.connect(3000); 

     LastLogin = _reader.readLine(); //get last login message 
    }//try to connect 
    catch (JSchException ex) 
    { 
     throw ex; 
    } 
    catch (UnsupportedEncodingException uee) 
    { 
     return false; 
    } 
    catch (IOException ioe) 
    { 
     return false; 
    } 
    return true; 
} 

這是我的執行方法。我知道從char []到ArrayList有一個更好的方法,但我還沒有解決這個問題。

public List<String> ExecuteCommand (String command) 
{ 

    List<String> returns = new ArrayList(); 
    try { 
     _writer.write(command); 


     if (!command.endsWith("\n")) 
      _writer.write("\n"); 

     _writer.flush(); 
     Thread.sleep(2000); //allow time to exec 

     int c; 
     StringBuilder response= new StringBuilder(); 

     while (_reader.ready()) { 
      c = _reader.read(); 
      if (c == -1) 
       break; 
      response.append((char)c) ; 
     }//while 

     String[] lines = response.toString().split("\n"); 
     for (String line: lines) 
     { 
      if (line.trim().length()!=0) 
       returns.add(line); 
     } 

    }//try 
    catch (IOException e) 
    { 
     //handle this later 
    }//catch 
    catch (InterruptedException ie) 
    { 
     //handle this later 
    } 
    return returns; 
}//ExecuteCommand 

我知道這不是很好,但它的工作原理。