javalinuxbashsshjsch

Execute a local script on a remote machine through Java JSch library


I am working on monitoring the logs for an error on a set of remote servers. For that I am monitoring logs that were modified within some time period.

I am using Jsch Java library to make a SSH connection and excute the commands. As I have searched, multiple commands can be remote machine by separating different commands by ;

For that I have a text file which contains the list on remote hosts on which I am establishing the connection. I realise that I can get the list of all files that were modified by the following command

find . -mmin -60 -type f -exec ls {} +

No I can loop over the files and grep for the Error. For this I have written the following script

logTestScript.sh

#!/bin/bash

cd /log
searchString='<Error ErrorCode="java.sql.SQLException"'
files=`find . -mmin -60 -type f -exec ls {} +`
pwd
hostname
echo ${files}
for file in ${files[@]}
do
        if grep -Fq "$searchString" $file
        then
                echo "String found in $file"
        fi
done

Now this script is present in the current package from which I am running a java program and I wish to run this script on each of the remote host.

Below is my current code making use of ChannelExec

private void getSSHConnection() throws IOException, JSchException {

        username = props.getProperty("host_username");
        password = props.getProperty("host_password");
        log_traceback_interval = props.getProperty("fetch_logs_interval_minutes");
        errorString = props.getProperty("error_message_log");

        System.out.println(username + " " + password + " " + errorString);

        // Get the hostnames resource file
        String hostnameResourcePath = envObj.getAgentHostnamesConfig(TargetEnvironment, ManagementSystem);
        InputStream hostInpStream = this.getClass().getResourceAsStream(hostnameResourcePath);
        BufferedReader hostnameReader = new BufferedReader(new InputStreamReader(hostInpStream));

        String host = null;

        while((host = hostnameReader.readLine()) != null) {

            System.out.println(host);

            // get a JSch connection object
            JSch jschObj = new JSch();
            Session session = jschObj.getSession(username, host);

            // Disable StrictHost key checking
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            session.setPassword(password);
            session.connect();

            //Execute channel instance
            ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
            InputStream in = channelExec.getInputStream();

            //Bash script command with arguments
            StringBuilder sb = new StringBuilder();
            String command = sb.append("cd /log").append(";")
                                .append("echo `find . -mmin -60 -type f -exec ls {} +`").append(";")
                                .toString();   

            System.out.println(command);

            //Run the script on host
            channelExec.setCommand(command);    //I want to run the script here instead of each command as it uses for loop

            channelExec.setInputStream(null);

            channelExec.setErrStream(System.err);

            InputStream monitorLogs = channelExec.getInputStream();

            channelExec.connect();

            //Read the logs
            BufferedReader logReader = new BufferedReader(new InputStreamReader(monitorLogs));
            String logLine;

            while((logLine = logReader.readLine()) != null) {

                System.out.println(logLine);
            }

            //Close the connections
            channelExec.disconnect();
            session.disconnect();
        }




    }

One solution that I can think of if to SCP the script on to the remote host and then executing it there.

However Is there some simple solution, with which I can acieve the same result even without writing the script and only executing commands or executing the script on the remote server.

Thanks for help


Solution

  • You cannot execute a local script on a server.

    You have two options (that you are obviously aware of):


    Ntb, "echo `pwd`" and "echo `hostname`" do not make sense. Use "pwd" and "hostname" directly.