我使用以下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
这个问题似乎与我如何启动终端有关。通过修改环境变量启动其他应用程序可以正常工作。
如何启动终端以便它接受我的环境变量修改,即使终端已经打开了?
答案 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来执行osascript
和pwd
来获取值当前工作目录和osascript进程的echo $PATH
变量 到AppleScript变量中,然后我们将其注入新终端。首先对{“1”}执行“当前”目录,然后对指定的PATH
执行另一个cd
,这将处理相对路径和绝对路径。
最后请注意cd
打印脚本的返回值,因此在执行dirParam
之前应确保使用所有进程输出(或者如果您使用的是Java 7,则可以使用osascript
{1}}和waitFor
)相同。
答案 1 :(得分:2)
一些想法 - 我无法尝试任何事情,因为我只有Linux在工作。
您正在通过open
命令打开终端。也许如果直接运行终端可执行文件(我想你需要转到.app文件夹中的实际二进制文件),你的环境设置会通过吗?
或者,另一种启动终端的方法是open
保存的终端首选项文件(扩展名.terminal,通过Terminal.app的Preferences面板创建)。这将打开一个设置了这些首选项的终端。多年来我一直没有修改终端偏好,但也许有办法在那里设置路径?