JSch问题 – 无法检索完整命令输出

我正在使用JSch连接到SSH并执行命令。 其中一个命令给出了很大的输出。 在终端中,如果执行命令,则必须按Enter键才能查看整个输出。 使用JSch我无法检索整个输出。

当我使用交互式终端登录时,命令输出在填满屏幕后停止并等待Enter

代码取自如何在String中获取jsch shell命令输出 :

public class SshConnectionManager { private static Session session; private static ChannelShell channel; private static String username = ""; private static String password = ""; private static String hostname = ""; private static Session getSession(){ if(session == null || !session.isConnected()){ session = connect(hostname,username,password); } return session; } private static Channel getChannel(){ if(channel == null || !channel.isConnected()){ try{ channel = (ChannelShell)getSession().openChannel("shell"); channel.connect(); }catch(Exception e){ System.out.println("Error while opening channel: "+ e); } } return channel; } private static Session connect(String hostname, String username, String password){ JSch jSch = new JSch(); try { session = jSch.getSession(username, hostname, 22); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setPassword(password); System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... "); session.connect(); System.out.println("Connected!"); }catch(Exception e){ System.out.println("An error occurred while connecting to "+hostname+": "+e); } return session; } private static void executeCommands(List commands){ try{ Channel channel=getChannel(); System.out.println("Sending commands..."); sendCommands(channel, commands); readChannelOutput(channel); System.out.println("Finished sending commands!"); }catch(Exception e){ System.out.println("An error ocurred during executeCommands: "+e); } } private static void sendCommands(Channel channel, List commands){ try{ PrintStream out = new PrintStream(channel.getOutputStream()); out.println("#!/bin/bash"); for(String command : commands){ out.println(command); } out.println("exit"); out.flush(); }catch(Exception e){ System.out.println("Error while sending commands: "+ e); } } private static void readChannelOutput(Channel channel){ byte[] buffer = new byte[1024]; try{ InputStream in = channel.getInputStream(); String line = ""; while (true){ while (in.available() > 0) { int i = in.read(buffer, 0, 1024); if (i < 0) { break; } line = new String(buffer, 0, i); System.out.println(line); } if(line.contains("logout")){ break; } if (channel.isClosed()){ break; } try { Thread.sleep(1000); } catch (Exception ee){} } }catch(Exception e){ System.out.println("Error while reading channel output: "+ e); } } public static void close(){ channel.disconnect(); session.disconnect(); System.out.println("Disconnected channel and session"); } public static void main(String[] args){ List commands = new ArrayList(); commands.add("ls -l"); executeCommands(commands); close(); } } 

通常不应使用“shell”通道来自动执行命令。

“shell”通道旨在实现交互式shell会话。

因此它请求PTY(伪终端),它具有人性化但机器不友好的副作用,会破坏您的代码。

请改用“exec”频道。

请参阅使用Java中的JSch exec从ArrayList执行命令列表


如果您出于某种原因需要或想要使用“shell”频道(但不要,它会咬你),请确保在.setPty(false)之前调用.setPty(false)

 channel = (ChannelShell)getSession().openChannel("shell"); channel.setPty(false); channel.connect(); 

附注:

  • "#!/bin/bash"是一个纯粹的废话。 shell忽略所有以#开头的命令(它的注释)。 发送它没有意义。
  • 不要使用StrictHostKeyChecking=no 。 使用session.setConfig(“StrictHostKeyChecking”,“no”)查看JSch SFTP安全性; 。