0

Jsch in shell mode i want to execute commands sequentially. I tried using the below code. Problem with the code is code waits on readLine(). Can anybody suggest a solution. If you can please fix the below code

Note: i want to execute the commands in shell mode only

public class SSHClient1 {

    private  Session session;
    private  ChannelShell channel;
    private  String username = "";
    private  String password = "";
    private  String hostname = "";

    public SSHClient1(String username, String password, String hostname) throws Exception {
        super();
        this.username = username;
        this.password = password;
        this.hostname = hostname;
        startSession();
        intializeChannel();
    }

    private void startSession() throws Exception{
        if(session == null || !session.isConnected()){
            session = connect(hostname,username,password);
        }
    }

    private void intializeChannel() throws Exception{
        if(channel == null || !channel.isConnected()){
            try{
                channel = (ChannelShell)session.openChannel("shell");
                channel.setPty(false);
                channel.connect();
            }catch(Exception e){
            }
        }
    }

    private Session connect(String hostname, String username, String password) throws Exception{
        JSch jSch = new JSch();
        try {
            session = jSch.getSession(username, hostname, 22);
            Properties config = new Properties(); 
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setPassword(password);
            session.connect();
            System.out.println("Connected successfully to host "+ hostname);
        }catch(Exception e){
        }
        return session;
    }

    public void executeCommands(List<String> commands) throws Exception{
        PrintStream out = null;
        try{
            out = new PrintStream(channel.getOutputStream());
            for(String command : commands){
                out.println(command);
                out.flush();
                printResult();
            }

        }catch(Exception e){
        } finally{
            if(out != null)
                out.close();

        }
    }

    private void printResult() throws IOException{
        try{
            InputStream in = channel.getInputStream();
            String line = "";
            BufferedReader br =new  BufferedReader(new InputStreamReader(in));
            while((line = br.readLine()) != null){
                System.out.println(line);
            }
        }catch(Exception e){
        }

    }


    public void close(){ 
        if(channel != null)
            channel.disconnect();
        if(session != null)
            session.disconnect();
    }


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

        SSHClient1 ssh = new SSHClient1("admin", "password", "192.168.2.9");
        List<String> commands = new ArrayList<String>();
        commands.add("enable");
        commands.add("configure terminal");
        commands.add("show running-config");
        ssh.executeCommands(commands);
        ssh.close();

    }
}

if i change two methods of the above code i was able to achieve what i want, the problem with the approach is i need to put a Thread.sleep after creating the buffer other wise it will not print any thing.

public void executeCommands(List<String> commands) throws Exception{
        PrintStream out = null;
        try{
            out = new PrintStream(channel.getOutputStream(),true);
            for(String command : commands){
                out.println(command);
                out.flush();
                printResult();
            }
        }catch(Exception e){
        } finally{
            if(out != null)
                out.close();

        }
    }

    private void printResult() throws IOException{
        try{
            InputStream in = channel.getInputStream();
            BufferedReader br =new  BufferedReader(new InputStreamReader(in));
            Thread.sleep(10000);
            boolean ready = false;
            int c = 0;
            StringBuilder line = new StringBuilder();
            while((ready = br.ready()) == true){
                ready = br.ready();
                c = br.read();
                System.out.print(String.valueOf((char)c));
            }
        }catch(Exception e){
        }
    }
0

2 Answers 2

1

if wrapping the commands is an option, you can do :

# cat /usr/bin/your-enable
#!/bin/bash
enable
echo "#END#"

change main (example):

 commands.add("/usr/bin/your-enable");

change printResult :

while((line = br.readLine()) != null){

    if (line.equals("#END#")) {
       break;
    } else {
       System.out.println(line);
    }
}

Hope it helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Yair in my case that is not possible.
so you can add new command which will separate your commands : "echo "#END#"" and use the same code in the printResult. you will have to send 2 command each time before going to read.
i am not working on a linux machine. its a ssh enabled router which has only few commands. Secondly in my case br.readLine itself pauses
0

Was able to find a solution. Has put a busy spin until br.ready() is true. We need to put a Thread.sleep also before putting a busy loop

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.