Изменить путь при запуске терминала С Java

Я использую следующий код 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();

это приводит к открытию окна терминала, но изменения пути, похоже, игнорируются:

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

эта проблема, похоже, связана с тем, как я запускаю терминал. Запуск других приложений с изменением переменных среды работает нормально.

Как запустить терминал, чтобы он принимал мои изменения переменных среды, даже если терминал уже открыто?

2 ответов


в этом конкретном случае вы можете подделать его, используя 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();

если вы хотите заполнить и PATH значение из пользовательских параметров, тогда я бы рассмотрел использование on run чтобы скрипт принимал Аргументы и использовал quoted form of чтобы избежать каких-либо потенциальных проблем с цитированием:

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 трюк на стороне Java, но все еще хотите относительные пути (относительно текущего каталог 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();

это немного русская кукла - мы выполняем osascript от Java, который, в свою очередь, запускает свою собственную подсеть, чтобы сделать pwd и echo $PATH чтобы получить значения текущего рабочего каталога и PATH переменная процесса osascript в переменные AppleScript, которые мы затем вводим в новый терминал. Сначала сделав cd к" текущему " реж., а затем еще один cd к указанному dirParam это будет обрабатывать как относительные, так и абсолютные пути.

наконец, обратите внимание, что osascript печатает возвращаемое значение скрипта, поэтому перед выполнением waitFor (или если вы на Java 7, Вы можете использовать processBuilder.redirectOutput(new File("/dev/null")) и то же самое для redirectError).


пара мыслей - я не могу ничего попробовать, так как у меня только Linux на работе.

вы открываете терминал через . Возможно, если вы запустите исполняемый файл терминала напрямую (я думаю, вам нужно перейти к фактическому двоичному файлу внутри .App folder) ваши настройки среды будут проходить через?

кроме того, другой способ запуска терминала open сохраненный файл настроек терминала (расширение .терминал создан по предпочтениям панель терминала.приложение.) Откроется терминал с заданными параметрами. Я не возился с настройками терминала в течение многих лет, но, возможно, есть способ установить путь туда?