2014-04-07 5 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; 
} 

입니다. 결과에 따라 행동하고 더 많은 명령을 보내십시오. 나는 그들이 그 앞에 오는 명령을 쌓을 때마다 매번 연결을 닫고 싶지 않습니다. 내가 찾고있는 결과를 얻기에 충분한 Inputs와 Output Streams로 작업하는 방법을 모르겠습니다. 다음 방법을 작성하는 데 도움을받을 수 있다면 감사 할 것입니다.

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

감사

+0

멀티 라인 String (명령)을 사용하고 행의 ArrayList를 만들고 싶습니까? 그게 다야? –

+0

꽤 많이 있습니다. 이 시점에서 Java에서 스트림을 처리하는 방법은 확실하지 않습니다. 내 목표는 다음과 같이하는 것입니다. 목록 결과 = 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을 지원하는 가장 중요한 코드 스 니펫입니다. 이 예에서, 오류 출력을 표준 출력으로 재 지정합니다. 오류 출력을 원하지 않으면 제거 할 수 있습니다. 예제에서는 List <String> 대신 StringWriter를 사용합니다. 나는 그것을 사용하는 것이 좋습니다.

/** 
* 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 

나는 위대하다고 생각하지 않지만 작동합니다.