简体   繁体   中英

How to run a Linux script(already added to the $PATH) from Java?

I'm trying to run a script with Runtime.getRuntime().exec , but nothing happens. Here's an example of what I mean:

class Test {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime().exec("script.sh");
        System.out.println("done");
    }
}

Here's script.sh :

#!/bin/sh
echo "It works"

I have added the sh file's location to the PATH because I don't want to hard code it's location. In the terminal both the above script works from any location(directory):

$ script.sh
It works

But not via Java:

$ javac Test.java && java Test
done

This is what I expected:

$ javac Test.java && java Test
It works
done

Why don't I get the script's output, or at least an error message?

You are responsible for ensuring that any data the command writes to stdout or stderr is surfaced in your application.

If you don't explicitly do anything, messages will not be shown anywhere. Instead they'll be stuck in a pipe buffer somewhere. Here's your example without the script.sh dependency, using ls as an example to write both output and errors:

$ ls -d /tmp /doesntexist
ls: /doesntexist: No such file or directory
/tmp

$ cat Test.java
class Test {
    public static void main(String[] args) throws Exception {
        Runtime.getRuntime().exec("ls -d /tmp /doesntexist");
    }
}

$ javac Test.java && java Test
(no output)

If you simply want to show output and errors on the terminal where you run your Java program, let the process inherit Java's stdout/stderr:

$ cat Test.java
class Test {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("ls", "-d", "/tmp", "/doesntexist");
        pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        pb.redirectError (ProcessBuilder.Redirect.INHERIT);
        pb.start();
    }
}

$ javac Test.java && java Test
ls: /doesntexist: No such file or directory
/tmp

You can try Process API

ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "script.sh");
Process process = builder.start();

update try to add environment manually (just for now)

    ProcessBuilder builder = new ProcessBuilder();
    builder.command("sh", "script.sh");
    Map<String, String> env = builder.environment();
    env.put("PATH", "/yourpath/");
    Process process = builder.start();

Can your environment see the new PATH you set? You can check with:

ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "printenv";
Process process = builder.start();

If not, where are you setting the PATH variable from? It sounds like a terminal window, which does not update your environment variables universally.

Try to export the path, then run an executable JAR of your program from the same shell:

export PATH=$PATH:/path/to/script.sh
java -jar program.jar

If you are running from an IDE, you can set the PATH variable and run the IDE from the same terminal instance.

Have you tried running with the full path of the script first?

Have you tried:

runtime.getruntime().exec("sh -c script.sh");

Might not be necessarily an issue pertaining to java, sometimes linux acts weird.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM