改变System.in并动态读取System.out程序(Jsch)

在我的代码中,我试图通过SSH在远程服务器上运行一些命令。 命令必须相互构建,但背后有一个逻辑。 这意味着:当命令a的输出包含“retcode 0”时,则执行命令b。 否则做命令c

我发现没有办法将这个逻辑实现到几个“exec”命令中。 看起来每个“exec”都有自己的过程,所以我无法继续前进。 并且使用一个“exec”我只能传递一个命令列表,其中所有命令都将被执行,因此没有逻辑。 所以,我决定为Jsch使用“shell”。 (如果有办法使用exec,我会很高兴)

根据jcraft的例子,我写了这段代码:

import com.jcraft.jsch.*; import java.io.ByteArrayInputStream; import java.io.InputStream; public class Main { public static void main(String[] args) { try { JSch jsch = new JSch(); String user = "sshuser"; String host = "localhost"; Session session = jsch.getSession(user, host, 22); String passwd = "password"; session.setPassword(passwd); session.setConfig("StrictHostKeyChecking", "no"); //session.connect(); session.connect(30000); // making a connection with timeout. Channel channel = session.openChannel("shell"); // Enable agent-forwarding. ((ChannelShell)channel).setAgentForwarding(true); // Set Streams channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(3 * 1000); } catch (Exception e) { System.out.println(e); } } } 

基本上,这让我作为一个人类完全有可能做我想做的事情。 我可以在System.in中输入命令,返回打印到System.out。 我可以阅读它,决定我想用它做什么,然后输入下一个命令。 该命令将在我之前的位置完全执行,所以一切都很好。

现在我必须通过java找到一种方法。 我找到了通过修复字符串输入第一个命令的方法:

 [...] InputStream testInput = new ByteArrayInputStream( "dir \n".getBytes("UTF-8") ); // Set Streams channel.setInputStream(testInput); [...] 

但之后我发现无法发送下一个(即使没有读取输出也是第一步)。

所以,我的问题是,有没有办法通过Java代码设置System.in,它将直接通过Jsch发送(System.setIn()对我不起作用)或另一种方式来动态更改输入字符串,以便它通过Jsch传输?

谢谢你的时间!

感谢Martin Prikryl的评论,我找到了解决方案。 我用Telnet创建了一个小例子而不是我的真实应用程序。 基础是相同的,我认为它更有帮助,因为更多的人可以尝试它,并在不基于特定软件时使用它。

 import com.jcraft.jsch.*; import java.io.*; public class Main { public static void main(String[] args) { OutputStream out = null; Session session = null; try { JSch jsch = new JSch(); String user = "sshuser"; String host = "localhost"; session = jsch.getSession(user, host, 22); String passwd = "password"; session.setPassword(passwd); session.setConfig("StrictHostKeyChecking", "no"); // vars and objects used later String lineSeperator = System.getProperty("line.separator"); StringBuilder sb = new StringBuilder(); Main main = new Main(); //session.connect(); session.connect(30000); // making a connection with timeout. ChannelExec channel = (ChannelExec) session.openChannel("exec"); InputStream in = channel.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); // start telnet session channel.setCommand("telnet 192.168.222.128 -l sshuser"); out = channel.getOutputStream(); channel.connect(); // wait a little bit for telnet to be ready to take the input Thread.sleep(500); // pass the password out.write(("password\n").getBytes()); out.write(("\n").getBytes()); Thread.sleep(500); // flush reader, very important! out.flush(); // Read from Bufferreader until the current line contains a specific string // For my real application it would be "--- END", for this example i // used something from the last line my machine returns. Very important that this string // appears on every possible output, or you will stuck in a while loop! // // Tried it with while((reader.readline())!=null) but this ends in a infinity loop too. // Since in my application there is an String that always get returned i didn't look it further up String responeFromLogin = main.readOutput("security updates.", reader, lineSeperator, sb); // Working with the response, in this example a simple fail-->Exception, success --> progress if (responeFromLogin.contains("Login incorrect")) { throw new Exception("Failed: Login"); } System.out.println("Login Successfull"); // Log in was successful, so lets do the next command, basiclly the same routine again out.write(("dir\n").getBytes()); Thread.sleep(500); out.flush(); // Again, not bulletproofed in this example String responseFromHelp = main.readOutput("examples.desktop", reader, lineSeperator, sb); if (!responseFromHelp.contains("test")) { throw new Exception("Failed: Help"); } System.out.println("Folder Found"); } catch (InterruptedException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } catch (JSchException e1) { e1.printStackTrace(); } catch (Exception e1) { e1.printStackTrace(); } finally { try { if (out != null) { out.flush(); } } catch (IOException e1) { e1.printStackTrace(); } System.out.println("_________________________"); System.out.println("I am done"); if (session != null) { session.disconnect(); } } } public String readOutput(String endString, BufferedReader reader, String lineSeperator, StringBuilder sb) { String line; String returnString = "Error"; while (true) { try { line = reader.readLine(); if (line.contains(endString)) { sb.append(line).append(lineSeperator); returnString = sb.toString(); break; } else { sb.append(line).append(lineSeperator); } } catch (IOException e) { returnString = "Error"; e.printStackTrace(); } } return returnString; } }