Why does reading from a shell channel output in JSch never end with -1?

会有一股神秘感。 提交于 2019-12-07 16:16:58

问题


I created an object called Obj which sends messages over a Secure Shell channel. I can send characters in UTF-8, which means that the output stream must handle multi-byte characters. That is why I decided to use a buffered output stream writer. That is not relevant, so the code only references that part of the code with a comment.

I'd like the input stream to also handle multibyte characters. I know that the read() function of the InputStreamReader will return integers that correspond to UTF-16 code points or -1. My current implementation loops and tests for -1. It loops endlessly. Why?

Code

Here is my source code

public class Obj {

    public String sendMessage(char[] message) {

        final int CONNECTION_TIMEOUT_MILLISECONDS = 300;
        final int IN_BUFFER_SIZE = 2048;
        int codePoint;
        StringBuilder sbResponse = new StringBuilder();

        try {
            ChannelShell channel = SshChannelFactory.getChannel(this);
            if (channel == null) {
                System.out.println("Unable to acquire channel for object \"{}\"", this);
                throw new RuntimeException();
            }
            channel.connect(CONNECTION_TIMEOUT_MILLISECONDS);
            System.out.println("Successfully opened channel to \"{}\"", channel.getHost());
        }

        /**
         * Write some stuff in this try block.
         */
        //try {
        //} catch

        /**
         * Read the response in this try block.
         */
        char[] buffer = new char[IN_BUFFER_SIZE];
        int bytesReadOffset = 0;
        try {
            BufferedReader fromServerStream = new BufferedReader(new InputStreamReader(channel.getInputStream(), Charset.forName("UTF-8")), IN_BUFFER_SIZE);
            while ((codePoint = fromServerStream.read()) != -1) {
                sbResponse.append((char) codePoint);
            } catch (IOException e) {
              e.printStackTrace();
            }
        return sbResponse.toString();
}

public class SshChannelFactory {

    public static ChannelShell getChannel(Obj obj) {
        return createSshChannel(obj);
    }

    private static Session createSshSession(Obj obj) {
        final JSch jsch = new JSch();
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        try {

            Session session = jsch.getSession(obj.getUser(), obj.getHost(), obj.getPort());
            session.connect();
            return session;
        } catch (JschException e) {
          e.printStackTrace();
          throw new RuntimeException();
        }
    }

    private static ChannelShell createSshChannel() {
        Session session = SSHSessionFactory.createSshSession(Obj obj)
        try {
            ChannelShell channel = (ChannelShell) session.openChannel("shell");
            channel.setPty(true);
            channel.setInputStream(null);
            channel.setOutputStream(null);
            return channel;
        } catch (JSchException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
}

回答1:


The "shell" channel opens a shell.

We do not know what your code actually does. But I'd assume that you send some command to the shell to be executed and then you try to read the command output. And you probably expect to get -1 once the command output ends. You won't.

The shell output stream ends, only when the shell ends. And for that you need to send some command like exit.


In general, you should not use the "shell" channel. It's intended for implementing an interactive shell session (like if you are implementing your own SSH terminal). That's something you rarely do.

To automate a command execution, use the "exec" channel.

See also What is the difference between the 'shell' channel and the 'exec' channel in JSch.



来源:https://stackoverflow.com/questions/56737291/why-does-reading-from-a-shell-channel-output-in-jsch-never-end-with-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!