java - 如何使用 JSch 执行交互式命令并从 Java 读取其稀疏输出

标签 java ssh inputstream jsch

目前我可以使用 JSch 库在 SSH session 中执行远程命令,如下所示:

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 似乎不仅在 session / channel 关闭时返回 -1,而且还返回 -1当暂时没有输入数据时。

您最好使用channel.isClosed()来测试 session / channel 是否关闭。请参阅official Exec.java example :

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 的代码会在控制台上打印输出,因为您已通过以下方式指示它:

channel.setOutputStream(System.out, true);

您必须实现输出流才能写入字符串。请参阅Get an OutputStream into a String

或者实际上,您应该能够使用与“exec” channel 相同的代码。

关于java - 如何使用 JSch 执行交互式命令并从 Java 读取其稀疏输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29899720/

相关文章:

java - 用整数序列填充数组并打印的方法

java - Java中二维数组转一维数组

git - 将提交推送到 amazon ec2 时权限被拒绝(公钥)

php - 执行命令给 top : failed tty get

C# - 关闭子进程的输入流

java - InputStream 到 servletInputStream

java - 从 Java 中的输入流中读取一行文本,保留行终止字符

java - SBT 设置 javac 最大堆

java - 使用 ActionListener 重新绘制图形 PaintComponent