Search code examples
javamacosruntime.execprocessbuilder

Running external script from Java application on OS X


I'm having real issues getting an external script to run from my Java application on OS X 10.8. It works on Windows, so not sure what I'm doing wrong for OS X.

What works (Windows):

String[] commands = {
    "\"" + _appDataDir + "\\Temp\\Workers\\" + _batchName + "\"", 
    "\"" + _appDataDir + "\\Temp\\frame%d.jpg\"", 
    "\"" + _fileName + "\""};
proc = rt.exec(commands);

So I have the following for OS X:

String[] commands = {
    _appDataDir + "/Temp/Workers/" + _batchName,
_appDataDir + "/Temp/Workers/mac-ffmpeg",   
_appDataDir + "/Temp/frame%d.jpg", 
"\"" + _fileName + "\""};
proc = rt.exec(commands);

This works when there are no spaces in the filename, but fails when there are spaces with a "java.io.IOException: Bad file descriptor" error.

At the moment, I've changed all the paths to have no spaces as an easy fix, but I don't have control over the fileName string as this is selected by the user from a save dialog. I've tried with and without double quotes around fileName but neither make any difference.

I also tried ProcessBuilder as below (both with and without the "/bin/bash/, -c" bits):

ProcessBuilder proc2 = new ProcessBuilder(
    "/bin/bash",
"-c",
_appDataDir + "/Temp/Workers/" + _batchName,
_appDataDir + "/Temp/Workers/mac-ffmpeg",
_appDataDir + "/Temp/frame%d.jpg",
"\"" + _fileName + "\""
);
proc = proc2.start();

but this gives the same error. As far as I can tell I'm doing everything that's being suggested in other similar questions, but nothing is working. Any ideas would be appreciated!


Solution

  • You don't need the quotes around "\"" + _fileName + "\"", just a plain _fileName would work here. When you provide an array to Runtime.exec (or to ProcessBuilder) you've already split your command up into "words" - if you add the quotes you're telling it to look for a file whose name is actually double-quote + _fileName + double-quote rather than just _fileName.

    The real problem is likely to lie within the _batchName program, which presumably is a shell script that does the real work by calling other programs. Within that script you will receive the mac-ffmpeg, frame%d.jpg and _fileName arguments as $1, $2 and $3, and you need to make sure that they are properly quoted within the script, e.g. if the script currently says something like

    processFile $3
    

    then you need to change it to say

    processFile "$3"
    

    if it is to cope with file names that contain spaces. Or if it is set up to handle multiple files at once:

    processFiles $*
    

    then you need to replace that with

    processFiles "$@"