Search code examples
javalinuxsshpass

ssh to remote host using sshpass and fetch results using java


I'm trying to run some commands on a remote machine and capture the result using Java. I have a shell script called test.sh which has following commands:

sshpass -p 'password' ssh [email protected] echo hostname

I'm running it using below java code:

public void runCommand() throws IOException, InterruptedException {

    ProcessBuilder builder = new ProcessBuilder();
    boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
    if (isWindows) {
        builder.command("cmd.exe", "/c", "dir");
    } else {
        builder.command("sh", "-c", "sh test.sh");
    }
    builder.directory(new File(System.getProperty("user.home")));
    Process process;
    BufferedReader reader = null;
    try {
        process = builder.start();
        reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        String output = stringBuilder.toString();
        System.out.println(output);
    } finally

    {
        if (reader != null)
            try {
                reader.close();
            } catch (IOException e) {
            }
    }
}

The command executes but I'm not getting anything in the output. If I use simple commands like echo, hostname then I'm able to get the result in output. I know of JSch which can solve the problem, but I can't use it.


Solution

  • When starting a Process in Java, you must consume both stdout and stderr to avoid blocking, and you should log or control both (avoid consume-to-discard). There are now easier solutions than what the linked article mentions, using ProcessBuilder.

    In this instance you completely ignore error output from your command. You said your process exits with status code 127, so it probably prints on stderr so you will obtain more details about the error by using ProcessBuilder.redirectErrorStream(true).

    Probably sshpass not installed, or installed but not in $PATH for your java process.