Search code examples
javalinuxjsch

Jsch handling command confirm yes or no


I'm trying to handle confirmation question(y/n) with linux commands with Jsch. I'm able to get the question in error stream. But after writing a 'y' as answer in the output stream, the command does not get it. The SAMPLE command I try with is 'rm -i file1.txt' and after writing 'y' the file is not getting deleted.

My target command also returns results after confirming 'y' which should be read from input stream. echo y | is not an option for me with the target command.

        java.util.Properties config = new java.util.Properties();

        config.put("StrictHostKeyChecking", "no");
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, 22);
        session.setPassword(password);
        session.setConfig(config);
        session.connect();
        System.out.println("Connected");

        System.out.println(command);
        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);
        channel.setInputStream(null);

        InputStream in = channel.getInputStream();
        OutputStream outChannel = channel.getOutputStream();
        InputStream errStream = channel.getErrStream();
        PrintWriter writer = new PrintWriter(outChannel);
        channel.connect();

        byte[] errTmp = new byte[1024];
        while (errStream.available() > 0) {
            int i = errStream.read(errTmp, 0, 1024);
            if (i < 0)
                break;
            sysout = new String(errTmp, 0, i);
            System.out.println("Error Line:"+sysout);
            if(sysout.toLowerCase().contains("remove regular file")) {
                writer.println("y"); // Works till here but not deleting file
            }
        }

        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) { 
                int i = in.read(tmp, 0, 1024);
                if (i < 0)
                    break;
                sysout = new String(tmp, 0, i);                 
                System.out.println(sysout);
            }
            if (channel.isClosed()) {
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
            }
            channel.disconnect();
        }
        session.disconnect();
        out.close();
        System.out.println("DONE");

Solution

  • PrintWriters do not auto-flush unless asked to, so I believe you're closing the channel without having ever actually sent the y.

    You can create a PrintWriter that will autoflush when println is called by using the PrintWriter(OutputStream out, boolean autoflush) constructor.

    I also think you should avoid calling channel.disconnect() in your while (true) loop that waits for a result as you can be sure you won't get one once you close the channel.