3 votes

Pourquoi la lecture de la sortie d'un canal shell dans JSch ne se termine jamais par -1 ?

J'ai créé un objet appelé Obj qui envoie des messages sur un canal Secure Shell. Je peux envoyer des caractères en UTF-8, ce qui signifie que le flux de sortie doit gérer les caractères multi-octets. C'est pourquoi j'ai décidé d'utiliser un écrivain de flux de sortie tamponné. Cela n'est pas pertinent, donc le code ne fait référence qu'à cette partie du code avec un commentaire.

J'aimerais que le flux d'entrée gère également les caractères multi-octets. Je sais que la fonction read() de l'InputStreamReader renvoie des entiers correspondant aux points de code UTF-16 ou -1. Mon implémentation actuelle boucle et teste pour -1. Elle boucle sans fin. Pourquoi ?

Voici mon code source :

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();
        }
    }
}

1voto

Martin Prikryl Points 4584

Le canal "shell" ouvre un shell.

Nous ne savons pas ce que votre code fait réellement. Mais je suppose que vous envoyez une commande au shell pour qu'il l'exécute, puis que vous essayez de lire la sortie de la commande. Et vous vous attendez probablement à obtenir -1 à la fin de la sortie de la commande. Tu ne le feras pas.

Le flux de sortie de l'interpréteur de commandes se termine, uniquement lorsque l'interpréteur de commandes se termine. Et pour cela, vous devez envoyer une commande comme exit .


En général, vous ne devez pas utiliser le canal "shell . Il est destiné à mettre en œuvre une session shell interactive (comme si vous mettiez en œuvre votre propre terminal SSH). C'est quelque chose que vous faites rarement.

Pour automatiser l'exécution d'une commande, utilisez le canal "exec".

Voir aussi Quelle est la différence entre le canal "shell" et le canal "exec" dans JSch ? .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X