Search code examples
javabashshellruntimeprocessbuilder

How to run shell script which is stored in a String variable using Java?


I need to execute a shell script in Java. My shell script is not in a file, it is actually stored in a String variable. I am getting my shell script details from some other application.

I know how to execute different commands in Java as shown below:

public static void main(final String[] args) throws IOException, InterruptedException {
    //Build command 
    List<String> commands = new ArrayList<String>();
    commands.add("/bin/cat");
    //Add arguments
    commands.add("/home/david/pk.txt");
    System.out.println(commands);

    //Run macro on target
    ProcessBuilder pb = new ProcessBuilder(commands);
    pb.directory(new File("/home/david"));
    pb.redirectErrorStream(true);
    Process process = pb.start();

    //Read output
    StringBuilder out = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line = null, previous = null;
    while ((line = br.readLine()) != null)
        if (!line.equals(previous)) {
            previous = line;
            out.append(line).append('\n');
            System.out.println(line);
        }

    //Check result
    if (process.waitFor() == 0) {
        System.out.println("Success!");
        System.exit(0);
    }

    //Abnormal termination: Log command parameters and output and throw ExecutionException
    System.err.println(commands);
    System.err.println(out.toString());
    System.exit(1);
}

In my case, I will have script information in a json string variable from which I am extracting the content of script:

{"script":"#!/bin/bash\n\necho \"Hello World\"\n"}

Below is my code in which I am extracting script content from above json and now I am not sure how can I execute this script and also pass some parameters to it. For now, I can pass any simple string parameters:

String script = extractScriptValue(path, "script"); // this will give back actual shell script

// now how can I execute this shell script using the same above program?
// Also how I can pass some parameters as well to any shell script?

After executing the above script, it should print out Hello World.


Solution

  • You need to start a Process with the shell, and then send your script to its input stream. The following is just a proof of concept, you'll need to change some things (like creating the process with ProcessBuilder):

    public static void main(String[] args) throws IOException, InterruptedException {
    
        // this is your script in a string
        String script = "#!/bin/bash\n\necho \"Hello World\"\n echo $val";
    
        List<String> commandList = new ArrayList<>();
        commandList.add("/bin/bash");
    
        ProcessBuilder builder = new ProcessBuilder(commandList);
        builder.environment().put("val", "42");
        builder.redirectErrorStream(true);
        Process shell = builder.start();
    
        // Send your script to the input of the shell, something
        // like doing cat script.sh | bash in the terminal
        try(OutputStream commands = shell.getOutputStream()) {
            commands.write(script.getBytes());
        }
    
        // read the outcome
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(shell.getInputStream()))) {
            String line;
            while((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
    
        // check the exit code
        int exitCode = shell.waitFor();
        System.out.println("EXIT CODE: " + exitCode);
    }