Thursday, July 28, 2011

Executing a Shell Script from Java

Using MySQL and Java? Check out an easier way: Yank

Today I figured out how to run a bash script from Java for the first time, and I wanted to jot down the essential steps needed to get it all working along with some things to watch out for. This is specific to mysqldump, but it should work for any script you have and want to run in the bash shell. This also demonstrates how to pass in an argument to the script.

Step 1: The first order of business in running a shell script from within a Java program is to setup a function that you can pass shell commands to. The following method takes a command as an argument and runs it in a bash shell. I put this method in a class called ExecUtils.

public static void execShellCmd(String cmd) {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(new String[] { "/bin/bash", "-c", cmd });
            int exitValue = process.waitFor();
            System.out.println("exit value: " + exitValue);
            BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = buf.readLine()) != null) {
                System.out.println("exec response: " + line);
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }

Step 2: Creating the script is pretty straight forward, but there are a few things to watch out for. For a bash script, you need #!/bin/bash on the first line. To pass an argument into the script, I used FILENAME=$1 and later used $FILENAME in my command. $1 represents the first argument. I also exit the script with the value returned from the mysqldump command.
#!/bin/bash
FILENAME=$1
exit mysqldump --user=username --password=pass --databases DB_XYZ | gzip -9 > temp/dump/$FILENAME
For this example, I placed my file, dump.sh in the directory '/temp'. One more thing to check is that your script is executable. Run this command in the terminal to make it executable:
sudo chmod 777 /temp/dump.sh

Step 3: Now just run the script through the execShellCmd method.
package mysql;

import java.util.Date;

import com.xeiam.utils.ExecUtils;

/**
 * This class demonstrates running a shell script from within Java
 */
public class MySQLDumpScript {

    public static void main(String[] args) {

        String fileName = "DUMPFILE.sql.gz";
        String shellCommand = "/temp/dump.sh " + fileName;
        ExecUtils.execShellCmd(shellCommand);
    }
}

You should now see a file called DUMPFILE.sql.gz in /temp/dump. Piece of Cake!!!

3 comments:

Unknown said...

Hi,
Is there a way to add a method to your MySQLDumpScript class to check and see if the script which im running from java appears on the console window to notify me that it is done running?

Tim Molter said...

@Adama 'm not sire. Sorry!

Prashanth said...

Thanks. Your solution helped me. I was using Runtime.getRuntime.execute() without any options. And I guess it was not using /bin/bash by default. Thanks a ton.