tangguo

如何在字符串中获取jsch shell命令输出

java

我正在使用JSCH -SSH库在“ shell”通道中执行命令,但找不到找到两种方法的方法:

1)如何查找命令是否在远程unix box上完全执行?

2)如何在String中捕获命令输出,而不是在System.out控制台上打印它?

下面是我的代码片段,可以在system.out上显示shell命令输出

注意:我不想使用“ exec”通道,因为它为每个命令启动一个新进程,并且不记得已导出的“ session”变量。我必须使用“ shell”通道。

以下是我的代码段。感谢您的帮助。

try{

  String commandToRun = "ls /tmp/*.log \n";
  if(channel.isClosed())
      channel=session.openChannel("shell");
  byte[] bytes = commandToRun.getBytes();
  ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
  channel.setInputStream(bais);
  InputStream ins=channel.getInputStream();
  channel.connect();
  channel.setOutputStream(System.out);//This prints on console. Need 2 capture in String somehow?

  //in-efficient way to allow command to execute completely on remote Unix machine
  //DO NOT know a better way, to know when command is executed completely
  Thread.sleep(5000L);
}
 catch(Exception e){
  System.out.println("Exception  in executeCommand() --->"+ e.getMessage());
  e.printStackTrace();
}

阅读 408

收藏
2020-11-19

共2个答案

小编典典

对于2)你可以使用 ByteArrayOutputStream

final ByteArrayOutputStream baos = new ByteArrayOutputStream();
channel.setOutputStream(baos);

然后从创建新字符串 new String(baos.toByteArray())

对于1,您是否尝试在命令末尾使用2>&1?

String commandToRun = "ls /tmp/*.log 2>&1 \n";
2020-11-19
小编典典

OP可能不再需要我的解决方案,但是正在寻找能够同时满足这两个条件的解决方案的其他任何人:1)等待命令在远程计算机上完成;2)将输出捕获为字符串;您可以尝试以下方法:

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<String> 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<String> 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<String> commands = new ArrayList<String>();
    commands.add("ls -l");

    executeCommands(commands);
    close();
}
}

如果您需要一次发送多个命令并保持通道打开以供以后使用,则此解决方案也很有用。

2020-11-19