1

I am running a bash script in Groovy by creating a JSch tunnel to a remote host and running the script on a defined path there with a couple of arguments. It works fine but I want it to throw an exception when I script is not found. When i manually try to run the script on the remote server when the script is absent, I get "No such file or directory" error. But I cannot see that error anywhere when I run the script through JSch. The other couple of Exceptions like "Auth failed" or "Connection timed out" work fine.

import java.io.IOException;
import java.io.InputStream;
import com.jcraft.jsch.*


                    //Connecting to JSch individual sessions
                    JSch jsch = new JSch();
                    jsch.addIdentity( "~/.ssh/id_rsa" );
                    jschSession = jsch.getSession(USERNAME, host, REMOTE_PORT);
                    jschSession.setConfig("StrictHostKeyChecking", "no");
                    jschSession.connect();
                    ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec");
                    log.info("Channel is open");
                    //Run the shell script with given parameters
                    channelExec.setCommand("sh " + pathtoscript + " \"" + arg1 + "\" "  + arg2);
                    channelExec.setErrStream(System.err);//Not really sure if this works on Groovy?
                    channelExec.connect();

                    InputStream inp = channelExec.getInputStream();
                    byte[] tmp = new byte[1024];
                    String shellOut = "";
                    while (true) {
                            while (inp.available() > 0) {
                                    int i = inp.read(tmp, 0, 1024);
                                    if (i < 0) {
                                            break;
                                    }
                                    shellOut= new String(tmp, 0, i);
                                    log.info(shellOut); //prints out the output when script is run
                            }
                            if (channelExec.isClosed()) {
                                    if (inp.available() > 0) {
                                            continue;
                                    }
                                    log.info("exit-status: " + channelExec.getExitStatus()); //keeps giving me exist-status as 127 when script is not found but I also want it to throw an exception which it doesn't
                                    break;
                            }
                            try {
                                    Thread.sleep(1000);
                                    } catch (Exception ee) {
                                            log.error("This is the error of input");
                            }
                    }

                    channelExec.disconnect();
            }

            catch(JSchException ex) {
                    log.error("Exception cause is: " + ex.getCause());
                    if(ex.getCause().toString().contains("Connection timed out")){
                            log.info("Connection timed out on " + obj.ipAddress);
                            //do something
                   }else(ex.getMessage().contains("Auth fail")){
                            log.info("Authorization failed on " + obj.ipAddress);
                            //do something

                   }
            }
            catch (IOException e) {
                    log.error("Catching exception", e);
                    e.printStackTrace(); //I thought this would print the "Script not found" exception but it doesn't
            }

This is the output when I create a JSch channel and run the script when the script is absent:

Creating JSch tunnel...
Channel is open
exit-status: 127
Session disconnected.
sdasf
  • 29
  • 1
  • 5

1 Answers1

1

If you want to throw an exception when the command produces an error output, you have to read the error output and convert it to an exception. The channelExec.setErrStream(System.err) won't do that for you.

For a complete code for reading all of command's output, see How to read JSch command output?

At the end of that code, you have the error output in errorBuffer.toString(). Instead of printing it, you will want to throw an exception.

You might also want to check the Channel.getExitStatus. A non-zero exit code typically indicates an error.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992