Я пишу консольное приложение Java, которое принимает входные параметры из переменных среды (Linux). Чтобы установить эти переменные, мое приложение должно "указать" сценарий оболочки. Я могу "исправить" сценарий с помощью Runtime.exec() или с ProcessBuilder, но я понятия не имею, как получить доступ к созданным переменным среды.
Есть мой сценарий оболочки (set_env.sh):
#!/bin/csh
setenv MY_DB DB_NAME
Существует Java-код для "источника" сценария выше:
ProcessBuilder pb = new ProcessBuilder("csh", "-c", "'source set_env.sh'");
Process p = null;
try {
p = pb.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Как я могу получить доступ к созданной переменной MY_DB или есть ли другое решение моей проблемы?
Любая помощь будет очень оценена. Заранее спасибо.
Хорошо, парни. Благодаря вашим ответам. Есть мое временное решение. Я написал еще один скрипт, который создает "источник" и эхо создает переменные. В коде Java я выполняю его, считывая входной поток процесса и анализируя его.
Вы можете получить доступ к переменным среды с помощью System#getenv()
и System#getenv(String name)
.
Из учебника Oracle:
import java.util.Map;
public class EnvMap {
public static void main (String[] args) {
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n",
envName,
env.get(envName));
}
}
}
Однако, как упоминалось Сильваном Леру и Сержем Баллестой, дочерний процесс, созданный с помощью Process#start()
не может изменить среду своих родителей.
Если вы настроите только несколько переменных, используемых вашим java-кодом, java Properties
, вероятно, лучше подходят.
Как я могу получить доступ к созданной переменной MY_DB или есть ли другое решение моей проблемы?
Вы не можете. Когда вы "отправляете" свой файл, он фактически считывается созданной вами суб-оболочкой. Изменена среда этой подколонки. Но модификация среды не распространяется на родительский процесс.
Как я понимаю, System.env инициализируется во время запуска JVM и не может быть изменен во время работы приложения. Да и Нет. Стандартные библиотеки Java не предоставляют необходимые вызовы для изменения текущей среды. Но не думайте, что среда как-то "заперта". Это на самом деле более просто: каждый процесс (оболочка, экземпляр JVM, все остальное) получает копию своей родительской среды при создании. Вы можете делать то, что хотите, с вашей копией, но поскольку это копия, она никак не связана со средой вашего родителя. Когда вы начинаете новый процесс, он, в свою очередь, получает копию вашей среды в момент ее создания.
Что касается "отсутствующего" метода setEnv
в Java, это может быть (?), Потому что кто-то из Sun подумал, что сломает мантру "пишите один раз, бегите везде", так как некоторые системы не имеют переменных среды? См. Как установить переменные среды из Java?
BTW. Если вам нужна настраиваемая среда для запуска внешнего процесса, вы можете создать собственную среду, используя второй параметр Runtime.html # exec