首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JSch Channel.getExitStatus不返回在"shell“信道中执行的命令状态。

JSch Channel.getExitStatus不返回在"shell“信道中执行的命令状态。
EN

Stack Overflow用户
提问于 2021-12-28 18:47:49
回答 1查看 180关注 0票数 1

我试图通过JSch - diff命令对文件进行比较。我希望通过Java代码获取状态,以了解文件是否等于,即echo $status。我怎样才能在java中做到这一点?

这是我要运行SSH命令的类。

代码语言:javascript
运行
复制
public class SSH {

    static Logger logger = LogManager.getLogger("sshLogger");
    static Process p;
    static String s;
    int exitStatus = -1;
    String user;
    String pass;
    String server;
    String command;
    public Channel channel;
    public Session session;
    public InputStream in;

    public SSH(String user, String pass, String server) {
        this.user = user;
        this.pass = pass;
        this.server = server;
        logger.debug("instance: " + user + "@" + server);
    }

    private Session getConnectedSession(String user, String pass, String server) throws JSchException {

        session = new JSch().getSession(user, server, 22);
        java.util.Properties config = new java.util.Properties();
        session.setPassword(pass);
        config.put("StrictHostKeyChecking", "no");
        config.put("PreferredAuthentications","publickey,keyboard-interactive,password");
        session.setConfig(config);

        logger.debug("get connected session at: " + server);
        session.connect();
        logger.debug("connected to session");

        return session;

    }

    public Channel getChannel() {

        // ByteArrayOutputStream byteArrOutSt = new ByteArrayOutputStream();

        try {
            session = getConnectedSession(user, pass, server);
            logger.debug("opening channel at: " + server);
            channel = session.openChannel("shell");
        } catch (JSchException e) {
            logger.error("failed to connect to: "+ user + "@"+ server);
            e.printStackTrace();
        }
        // channel.setOutputStream(baos);
        channel.setOutputStream(System.out);
        channel.setExtOutputStream(System.out, true);
        // channel.setPty(Boolean.FALSE);

        return channel;

    }

    public String commandBuilder(String... commands)  {

        StringBuilder commandString = new StringBuilder();
        for (String command : commands) {
            logger.debug("adding command: " + command);
            commandString.append(command + "\\n");
        }
        logger.debug("adding command: exit");
        commandString.append("exit\\n");
        String myCommand = commandString.toString().replace("\\n", "\n");
        return myCommand;
    }
    
    
    public String executeCommand(String myCommand) {
        channel = getChannel();
        //String finishedCommand = commandBuilder(myCommand);
        logger.debug(myCommand);
    
        StringBuilder outBuff = new StringBuilder();
        String outComm = null;
        channel.setInputStream(new ByteArrayInputStream(myCommand.getBytes(StandardCharsets.UTF_8)));
        try {
            in = channel.getInputStream();
            channel.connect();
            // read from the output
            System.out.println("printing");
            while (true) {
                for (int c; ((c = in.read()) >= 0);) {
                    outBuff.append((char) c);
                }

                if (channel.isClosed()) {
                    if (in.available() > 0)
                        continue;
                    exitStatus = channel.getExitStatus();
                    break;
                }
            }
        } catch (IOException e) {
            logger.error("failed while running or reading output of command: " + myCommand);
        } catch (JSchException e) {
            
            logger.error("failed to connect to server while running command: " + myCommand);
        }
        

        logger.info(outBuff.toString());
        return outBuff.toString();
    }

    
    public void endSession() {

        logger.debug("ending session");
        channel.disconnect();
        session.disconnect();
        logger.debug("disconnected channel and session");

        // print exit status
        logger.debug("Exit status of the execution: " + exitStatus);
        if (exitStatus == 0) {
            logger.debug(" (OK)\n");
        } else {
            logger.debug(" (NOK)\n");
        }
    }
    
    public String runCommand(String... commands) {
        
        // many commands as you want
        
        
        String output = null;
        String myCommands;
        myCommands = commandBuilder(commands);
        try {
            output = executeCommand(myCommands);
            endSession();
        } catch (Exception e) {
            logger.error("failed to run ssh comands: "+ commands);
            e.printStackTrace();
        } 
        return output;
        
    }
    
}

diff示例中使用SSH:

代码语言:javascript
运行
复制
SSH session = new SSH(user, pass, server);
session.runCommand("diff file1.xml file2.xml");
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-28 19:19:30

首先不要在"shell“通道中执行命令。"shell“是一个只有输入和输出的黑匣子。请参阅在JSch中,“shell”通道和“exec”通道有什么区别?

使用"exec“频道。在"exec“通道中,Channel.getExitStatus工作。

有关代码示例,请参见:如何读取JSch命令输出?

强制性警告:不要使用StrictHostKeyChecking=no盲目地接受所有主机密钥。这是一个安全漏洞。你失去了对https://en.wikipedia.org/wiki/Man-in-the-middle_attack的保护。有关正确(和安全)方法,请参见:https://stackoverflow.com/q/32852906/850848

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70511275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档