从Java启动终端时修改路径
我使用以下Java代码启动终端:从Java启动终端时修改路径,java,macos,osx-mavericks,Java,Macos,Osx Mavericks,我使用以下Java代码启动终端: final ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/open", "-b", "com.apple.Terminal", "/Volumes"); fina
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();
这个问题似乎与我如何启动终端有关。通过修改环境变量启动其他应用程序效果良好。
如何启动终端,使其接受我的环境变量修改,即使终端已经打开?在这种情况下,您可以通过使用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();
如果您不能在Java端执行getAbsolutePath
技巧,但仍然希望相对路径(相对于osascript
的当前目录)起作用,那么您需要这样的技巧:
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();
final ProcessBuilder ProcessBuilder=new ProcessBuilder(“/usr/bin/osascript”,
“-e”,“运行argv”,
“-e”,“将currentdir设置为(执行shell脚本\“pwd\”)”,
“-e”,“将currentpath设置为(执行shell脚本\“echo$PATH\”)”,
“-e”,“告诉应用程序\“终端\”执行脚本\”
+“cd\”&引用的currentdir格式&\”“
+“cd\”&argv&\”;第1项的引用格式
+“导出路径=\”&引用当前路径的形式“,
“-e”,“结束运行”,
dirParam);
最终映射环境=processBuilder.environment();
最终字符串路径=environment.get(“路径”);
put(“PATH”,pathParam+File.pathseptor+PATH);
最终流程=processBuilder.start();
process.waitFor();
这有点像俄罗斯玩偶——我们正在从Java执行osascript
,Java又运行自己的子shell来执行pwd
和echo$PATH
,以将当前工作目录和osascript进程的PATH
变量的值注入到AppleScript变量中,然后将其注入到新的Te中终止。首先对“当前”目录执行一个cd
,然后对指定的dirParam
执行另一个cd
,这将处理相对路径和绝对路径
最后请注意,
osascript
打印脚本的返回值,因此您应该确保在执行waitFor
(或者如果您使用的是Java 7,您可以使用processBuilder.redirectOutput(新文件(“/dev/null”)
,对于redirectError
,也可以使用相同的方法).一些想法-我不能尝试任何东西,因为我只有Linux在工作
您正在通过open
命令打开终端。如果您直接运行终端可执行文件(我想您需要转到.app文件夹中的实际二进制文件),您的环境设置会通过吗
或者,启动终端的另一种方法是
打开
保存的终端首选项文件(扩展名.terminal,通过terminal.app的首选项面板创建)。这将打开一个设置了这些首选项的终端。我已经多年没有修改终端首选项了,但也许有一种方法可以在其中设置路径?我相信它被忽略了,因为“环境”“是为了发射终端的外壳,而不是终端本身。就像您打开了一个终端并从CLI启动了另一个终端,然后更改了第一个终端的路径。您可能需要查看Terminal.app,看看是否可以传入一些东西让它运行,比如export PATH=xxx
,这个链接是否有帮助@乔恩:不,这没用。你读了我的问题了吗?我读了问题。Yerminal打开了什么外壳?它在它的首选项中?谢谢。我不是osascript专家-这可以调整吗,这样就可以从当前工作目录使用路径,并将路径作为参数传递(aka使用任何指定的路径)?@ThomasS。我已经添加了一些关于如何实现这一点的详细信息,使用新文件(relativePath)。getAbsolutePath()
是否可以从脚本本身获取当前工作目录(我们的Java代码设置启动命令的工作目录,并且不能更改以将其作为单独的参数提供)。@ThomasS。这个怎么样?我找不到本地AppleScript方法来访问osascript进程的当前工作目录,但是您可以使用do shell script“pwd”
通过生成子shell来实现同样的目的。
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();
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();