簡體   English   中英

如何使用 JSch 執行交互式命令並從 Java 中讀取它們的稀疏輸出

[英]How to execute interactive commands and read their sparse output from Java using JSch

目前我可以使用 JSch 庫在 SSH 會話中執行遠程命令,如下所示:

JSch jsch = new JSch();
Session session = jsch.getSession(username, host, 22);
session.setPassword(password);

Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);

session.connect();

ChannelExec channel = (ChannelExec) session.openChannel("exec");
BufferedReader in = new BufferedReader(new InputStreamReader(channel.getInputStream()));

channel.setCommand("ls -l");
channel.connect();

StringBuilder output = new StringBuilder();

String s = null;
while((s = in.readLine()) != null){
    output.append(s + "\n");
}

System.out.println(output);

立即返回完整值的命令工作正常,但一些交互式命令(如“Docker run”)每隔一秒左右(幾分鍾)返回一個值,並且之前的代碼只讀取返回的第一個值。

有什么方法可以讀取命令返回的值?


編輯

這是我現在的代碼:

public String executeCommand(String cmd) {
    try {
        Channel channel = session.openChannel("shell");

        OutputStream inputstream_for_the_channel = channel.getOutputStream();
        PrintStream commander = new PrintStream(inputstream_for_the_channel, true);

        channel.setOutputStream(System.out, true);

        channel.connect();

        commander.println(cmd);

        commander.close();

        do {
            Thread.sleep(1000);
        } while(!channel.isEOF());
    } catch(Exception e) {
        e.printStackTrace();
    }
    return null;
}

JSch getInputStream的實現方式,它的read似乎不僅在會話/通道關閉時返回-1 ,而且在暫時沒有輸入數據時也返回。

您最好使用channel.isClosed()來測試會話/通道是否關閉。 請參閱官方Exec.java示例

byte[] tmp=new byte[1024];
while(true){
  while(in.available()>0){
    int i=in.read(tmp, 0, 1024);
    if(i<0)break;
    System.out.print(new String(tmp, 0, i));
  }
  if(channel.isClosed()){
    if(in.available()>0) continue; 
    System.out.println("exit-status: "+channel.getExitStatus());
    break;
  }
  try{Thread.sleep(1000);}catch(Exception ee){}
}

您的帶有“shell”通道的代碼會在控制台上打印輸出,因為您已通過以下方式指示它:

channel.setOutputStream(System.out, true);

您必須實現輸出流以寫入字符串。 參閱將 OutputStream 轉換為字符串

或者實際上,您應該能夠使用與“exec”通道相同的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM