In this particular case you could fake it by using AppleScript to open the terminal:
final ProcessBuilder processBuilder = new ProcessBuilder(
"/usr/bin/osascript", "-e");
final Map<String, String> environment = processBuilder.environment();
final String path = environment.get("PATH");
processBuilder.command().add("tell application \"Terminal\" to do script \"" +
"cd /Volumes ; export PATH=\\\"/mypath:" + path + "\\\\"\"");
final Process process = processBuilder.start();
process.waitFor();
If you want to populate the cd
directory and the PATH
value from user-supplied parameters then I would consider using on run
to let the script take arguments, and use quoted form of
to avoid any potential issues with quoting:
final ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/osascript",
"-e", "on run argv",
"-e", " tell application \"Terminal\" to do script "
+ "\"cd \" & quoted form of item 1 of argv & \" ; "
+ "export PATH=\" & quoted form of item 2 of argv",
"-e", "end run");
// create a File and use getAbsolutePath to resolve any relative paths
// against this Java process's working directory.
File cdDir = new File(dirParam);
// this argument will be "item 1 of argv" to the AppleScript
processBuilder.command().add(cdDir.getAbsolutePath());
final Map<String, String> environment = processBuilder.environment();
final String path = environment.get("PATH");
File pathPrefix = new File(pathParam);
// and this will be "item 2 of argv"
processBuilder.command().add(
pathPrefix.getAbsolutePath() + File.pathSeparator + path);
final Process process = processBuilder.start();
process.waitFor();
If you can't do the getAbsolutePath
trick on the Java side but still want relative paths (relative to the current directory of osascript
) to work, then you'd need a trick like this:
final ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/osascript",
"-e", "on run argv",
"-e", " set currentdir to (do shell script \"pwd\")",
"-e", " set currentpath to (do shell script \"echo $PATH\")",
"-e", " tell application \"Terminal\" to do script \""
+ "cd \" & quoted form of currentdir & \" ; ""
+ "cd \" & quoted form of item 1 of argv & \" ; "
+ "export PATH=\" & quoted form of currentpath",
"-e", "end run",
dirParam);
final Map<String, String> environment = processBuilder.environment();
final String path = environment.get("PATH");
environment.put("PATH", pathParam + File.pathSeparator + path);
final Process process = processBuilder.start();
process.waitFor();
This is a bit of a Russian doll - we're executing osascript
from Java, which in turn runs its own subshell to do pwd
and echo $PATH
to get the values of the current working directory and the PATH
variable of the osascript process into AppleScript variables, which we then inject into the new Terminal. By first doing a cd
to the "current" dir, and then another cd
to the specified dirParam
this will handle both relative and absolute paths.
Finally note that osascript
prints the return value of the script, so you should make sure you consume all the process output before doing waitFor
(or if you're on Java 7 you can use processBuilder.redirectOutput(new File("/dev/null"))
and the same for redirectError
).