Change PATH when starting terminal with Java

I use the following Java code to run the terminal:

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

This leads to the opening of a terminal window, but PATH modifications seem to be ignored:

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

This problem seems to be related to the way I start the terminal. Running other applications with changing environment variables works fine.

How to start a terminal so that it accepts changes to my environment modification, even if the terminal is already open?

+6
source share
2 answers

In this particular case, you can fake it using AppleScript to open a 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 fill in the cd directory and the PATH value from the parameters provided by the user, I would think of using on run to allow the script to take arguments and use quoted form of to avoid any potential citing problem:

 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 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 cannot use the getAbsolutePath trick on the Java side, but still want relative paths to work (relative to the current osascript directory), you will 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 little Russian doll - we run osascript from Java, which in turn runs its own subshell to do pwd and echo $PATH to get the current working directory and PATH values ​​of the osascript process variable in the AppleScript variables, which we then enter into new terminal. First by making cd in the "current" dir, and then another cd to the specified dirParam , it will handle both relative and absolute paths.

Finally, note that osascript prints the return value of the script, so before executing waitFor (or if you can use the entire process output in Java 7), you can use processBuilder.redirectOutput(new File("/dev/null")) and same for redirectError ).

+4
source

A few thoughts - I can’t try anything, since I only have Linux at work.

You open a terminal using the open command. Perhaps if you run the terminal executable directly (I think you need to go to the actual binary inside the .app folder) through which the environment settings will go?

As an alternative, another way to launch the terminal is to open saved terminal settings file (.terminal extension created using the Terminal.app settings panel). This opens the terminal with the settings. I have not bothered with the terminal settings for many years, but maybe there is a way to set the path there?

+2
source

Source: https://habr.com/ru/post/957577/


All Articles