Установка и получение переменных среды «исходным кодом» сценария оболочки из кода Java

1

Я пишу консольное приложение 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 я выполняю его, считывая входной поток процесса и анализируя его.

  • 0
    Не уверен, что понял. Не могли бы вы опубликовать код, показывающий, что вы сделали и где застряли?
  • 2
    Это действительно плохой дизайн. Вы должны написать скрипт-обертку, который получает сценарий оболочки и затем выполняет вашу Java-программу. Реализация синтаксиса и семантики оболочки - это не дело Java или приложения.
Теги:

2 ответа

2

Вы можете получить доступ к переменным среды с помощью 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, вероятно, лучше подходят.

  • 0
    Как я понимаю, System.env инициализируется при запуске JVM и не может быть изменен во время жизни приложения.
  • 2
    @anton_l: Да! Точнее, дочерний процесс никогда не сможет изменить среду своего родителя, поэтому, если ваша JVM запускает оболочку, оболочка может изменять свою собственную среду (и ту, которая является ее потомками-энтузиантами ...), но среда JVM никогда не изменится.
1

Как я могу получить доступ к созданной переменной MY_DB или есть ли другое решение моей проблемы?

Вы не можете. Когда вы "отправляете" свой файл, он фактически считывается созданной вами суб-оболочкой. Изменена среда этой подколонки. Но модификация среды не распространяется на родительский процесс.

Как я понимаю, System.env инициализируется во время запуска JVM и не может быть изменен во время работы приложения. Да и Нет. Стандартные библиотеки Java не предоставляют необходимые вызовы для изменения текущей среды. Но не думайте, что среда как-то "заперта". Это на самом деле более просто: каждый процесс (оболочка, экземпляр JVM, все остальное) получает копию своей родительской среды при создании. Вы можете делать то, что хотите, с вашей копией, но поскольку это копия, она никак не связана со средой вашего родителя. Когда вы начинаете новый процесс, он, в свою очередь, получает копию вашей среды в момент ее создания.

Что касается "отсутствующего" метода setEnv в Java, это может быть (?), Потому что кто-то из Sun подумал, что сломает мантру "пишите один раз, бегите везде", так как некоторые системы не имеют переменных среды? См. Как установить переменные среды из Java?

BTW. Если вам нужна настраиваемая среда для запуска внешнего процесса, вы можете создать собственную среду, используя второй параметр Runtime.html # exec

Ещё вопросы

Сообщество Overcoder
Наверх
Меню