从Java启动Terminal时修改PATH

时间:2013-11-07 11:56:43

标签: java macos osx-mavericks

我使用以下Java代码来启动终端:

final ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/open", "-b",
                                                         "com.apple.Terminal",
                                                         "/Volumes");
final Map<String, String> environment = processBuilder.environment();
final String path = environment.get("PATH");
environment.put("PATH", "/mypath" + File.pathSeparator + path);
final Process process = processBuilder.start();
process.waitFor();

这会导致终端窗口被打开,但是PATH的修改似乎被忽略了:

Volumes$ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

这个问题似乎与我如何启动终端有关。通过修改环境变量启动其他应用程序可以正常工作。

如何启动终端以便它接受我的环境变量修改,即使终端已经打开了?

2 个答案:

答案 0 :(得分:4)

在这种特殊情况下,您可以使用AppleScript打开终端来伪造它:

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();

如果要从用户提供的参数填充cd目录和PATH值,那么我会考虑使用on run让脚本接受参数,并使用{{1避免引用的任何潜在问题:

quoted form of

如果您不能在Java端执行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(); 技巧但仍希望相对路径(相对于getAbsolutePath的当前目录)工作,那么您需要一个这样的技巧:

osascript

这是一个俄罗斯玩偶 - 我们正在从Java执行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(); ,后者又运行自己的子shell来执行osascriptpwd来获取值当前工作目录和osascript进程的echo $PATH变量 到AppleScript变量中,然后我们将其注入新终端。首先对{“1”}执行“当前”目录,然后对指定的PATH执行另一个cd,这将处理相对路径和绝对路径。

最后请注意cd打印脚本的返回值,因此在执行dirParam之前应确保使用所有进程输出(或者如果您使用的是Java 7,则可以使用osascript {1}}和waitFor)相同。

答案 1 :(得分:2)

一些想法 - 我无法尝试任何事情,因为我只有Linux在工作。

您正在通过open命令打开终端。也许如果直接运行终端可执行文件(我想你需要转到.app文件夹中的实际二进制文件),你的环境设置会通过吗?

或者,另一种启动终端的方法是open保存的终端首选项文件(扩展名.terminal,通过Terminal.app的Preferences面板创建)。这将打开一个设置了这些首选项的终端。多年来我一直没有修改终端偏好,但也许有办法在那里设置路径?