0

I am sending commands with JSch using a ChannelShell.
But I am getting trouble doing it against a Windows machine.

This is the code:

package example;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import com.jcraft.jsch.*;

public class JSchShell {

    private static JSch jsch = null;
    private static String user = null;
    private static String passwd = null;
    private static String host = null;      
    static String inputCommands = "dir\r\ncd ..\r\nexit\r\n";

    public static void main(String[] args) throws Exception {

        if (args.length < 3) {
            throw new RuntimeException("Params needed: <host/ip> <user> <passwd>");
        }

        host = args[0];
        user = args[1];
        passwd = args[2];

        jsch = new JSch();

        try {
            Session session = jsch.getSession(user, host, 22);
            session.setPassword(passwd);
            session.setConfig("StrictHostKeyChecking", "no");

            long startTime = System.nanoTime();
            System.out.println("Before session.connect()");
            session.connect();
            long endTime = System.nanoTime();
            long duration = (endTime - startTime);
            System.out.println("After session.connect() - Took:"+ duration/1000000 + "ms");

            startTime = System.nanoTime();
            Channel channel = session.openChannel("shell");

            InputStream in = new ByteArrayInputStream(inputCommands.getBytes(StandardCharsets.UTF_8));

            channel.setInputStream(in);     
            channel.setOutputStream(System.out, true);

            System.out.println("Before channel.connect()");
            channel.connect();

            do {
                Thread.sleep(1);
            } while(!channel.isEOF());

            endTime = System.nanoTime();
            duration = (endTime - startTime);
            System.out.println("After commands - Took:"+ duration/1000000 + "ms");

            session.disconnect();


        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

It works fine if I run it against a Unix machine, but it seems not to do anything against Windows machine.

Here is the output against a Unix machine (I just ssh to my localhost, but it works on others):

[sysadmin@unixhost jsch]$ java -jar jschShell.jar localhost user passwd 
Before session.connect()
After session.connect() - Took:340ms
Before channel.connect()
Last login: Tue Sep 20 16:05:30 2016 from localhost
#############################################################################
dir

cd ..

exit

[sysadmin@unixhost ~]$ dir
certificados  corina  corina-curl.tgz  keys-for-mft  tom
[sysadmin@unixhost ~]$ 
[sysadmin@unixhost ~]$ cd ..
[sysadmin@unixhost home]$ 
[sysadmin@unixhost home]$ exit
logout
After commands - Took:34ms
[sysadmin@unixhost jsch]$ 

Here is the output for a Windows machine:

[sysadmin@unixhost jsch]$ java -jar jschShell.jar windowshost user passwd
Before session.connect()
After session.connect() - Took:818ms
Before channel.connect()
Last login: Tue Sep 20 2016 15:58:20 +0100
After commands - Took:108ms
[sysadmin@unixhost jsch]$ 

This is driving me nuts... I have been testing ChannelExec, and I get it working on both machines. I have also used the approach of this answer to another JSch question, but I got a similar result.

Any hints?

Community
  • 1
  • 1
nephewtom
  • 2,941
  • 3
  • 35
  • 49
  • What SSH server are you using on Windows? – Martin Prikryl Sep 21 '16 at 06:01
  • Do not use "shell" channel for automating command execution, it causes you troubles only. Use the "exec" channel. – Martin Prikryl Sep 21 '16 at 06:02
  • Well, I already tried with 'exec', but I wanted to do it with 'shell', since we thought it could be faster if we do not close the Channel. It is a matter of performance study. What is best, open a shell channel and inject commands through its stream or use a exec channel? – nephewtom Sep 21 '16 at 09:20
  • The "shell" channel is not for automating commands. It's not a question of performance. The "shell" channel is for implementing and interactive session. Period. – Martin Prikryl Sep 21 '16 at 09:22
  • There's hardly any performance impact with opening new "exec" channel (it's not a new SSH session, it's just a virtual channel within an existing SSH session). – Martin Prikryl Sep 21 '16 at 09:23
  • Ok, that is what it was implied from the JSch code. That the Session did all the SSH handshake stuff, and later the Channel would handle what it is sending. Then, shouldn't I expect a faster behavior using ChannelShell than ChannelExec? I am assuming for you comments that the answer in 'No'. – nephewtom Sep 21 '16 at 11:04
  • Maybe slightly. But again, that's just out of the question. For example in the "shell" channel, how would you tell how a command ended up? You do not get its exit code. You have no way to tell what output belongs to what command. You have no way to tell that a command has fished at all. Etc.. – Martin Prikryl Sep 21 '16 at 11:09

0 Answers0