Оценка переменных среды в команде, запускаемой Java Runtime.exec () - PullRequest
4 голосов
/ 19 января 2010

У меня есть сценарии, в которых у меня есть Java-агент, который работает на нескольких платформах (в частности, Windows, Solaris и AIX). Я хотел бы выделить различия в структуре файловой системы, используя переменные среды в командной строке, которую я выполняю.

Насколько я могу судить, нет способа получить метод Runtime.exec() для разрешения / оценки любых переменных среды, на которые есть ссылка в команде String (или массиве Strings).

Я знаю, что если нажать кнопку push, я могу написать некоторый код для предварительной обработки команды String и разрешения переменных среды вручную (используя getEnv() и т. Д.). Однако мне интересно, есть ли более разумный способ сделать это, так как я уверен, что я не единственный человек, желающий сделать это, и я уверен, что есть подводные камни в «подборе» моей собственной реализации.

Ваши рекомендации и предложения приветствуются.

редактирование: Я хотел бы сослаться на переменные среды в командной строке, используя некоторые согласованные обозначения, такие как $ VAR и / или% VAR%. Не суетиться который.

редактирование: Чтобы было ясно, я хотел бы иметь возможность выполнять такие команды, как:

perl $SCRIPT_ROOT/somePerlScript.pl args

на хостах Windows и Unix с использованием Runtime.exec(). Я задаю команду в файле конфигурации, которая описывает список заданий для запуска, и она должна быть в состоянии работать на кросс-платформенной основе, поэтому я подумал, что переменная окружения будет полезна для учета различий файловой системы (/home/username/scripts против C:\foo\scripts ). Надеюсь, это поможет прояснить это.

Спасибо. Том

Ответы [ 4 ]

6 голосов
/ 19 января 2010

Я думаю, что неправильно понял ваш вопрос с моим первоначальным ответом. Если вы пытаетесь разрешить ссылки на переменные окружения в командных строках, которые вы сгенерировали из-в Java, я думаю, вам, возможно, придется «свернуть свои собственные».

Существует множество различных стандартов их расширения в зависимости от операционной системы. Кроме того, это обычно является функцией оболочки, поэтому даже в одной и той же ОС могут быть разные способы. Фактически стандартные функции активации процессов операционной системы (например, exec в Unix) не выполняют расширение командной строки.

Это действительно не так сложно, с Java 5 и более поздними версиями. Определяя стандарт для себя, я обычно использую стандарт Java, который вы видите в файлах политики безопасности, и некоторые расширенные определения файлов свойств - ${var} расширяется до ссылки на имя переменной / свойства. Что-то вроде:

    private static String expandCommandLine(final String cmd) {
        final Pattern vars = Pattern.compile("[$]\\{(\\S+)\\}");
        final Matcher m = vars.matcher(cmd);

        final StringBuffer sb = new StringBuffer(cmd.length());
        int lastMatchEnd = 0;
        while (m.find()) {
            sb.append(cmd.substring(lastMatchEnd, m.start()));
            final String envVar = m.group(1);
            final String envVal = System.getenv(envVar);
            if (envVal == null)
                sb.append(cmd.substring(m.start(), m.end()));
            else
                sb.append(envVal);
            lastMatchEnd = m.end();
        }
        sb.append(cmd.substring(lastMatchEnd));

        return sb.toString();
    }
1 голос
/ 08 июня 2012

регулярное выражение

[$]\\{(\\S+)\\}

является жадным (S+) и в случае xx ${a} xx ${b} xx будет соответствовать A} xx ${B вместо отдельно A и B Вы когда-нибудь тестировали его с несколькими переменными в cmd?

Так что, если нужно заменить несколько переменных. Должно быть

[$]\\{(\\S+?)\\}
1 голос
/ 19 января 2010

По какой причине системные свойства не будут работать? Используйте флаг -D в командной строке, затем вы можете получить его через System.getProperty

0 голосов
/ 03 апреля 2010

Только потому, что у меня в буфере обмена есть код разрешения переменной среды Windows (действительно кодированный вами), который работает со строкой, я просто опубликую его здесь.Это, пожалуй, самый эффективный метод (может быть, регулярное выражение гораздо менее эффективно, я не уверен).

int from      = 0;
int startperc = -1;
int endperc   = -1;

while (true) {
    int index = tok.indexOf("%", from);
    if (index == -1) break;
    if (startperc == -1) {
        startperc = index;
    } else if (endperc == -1) {
        endperc = index;
    }
    from = index + 1;

    if (startperc >= 0 && endperc > startperc) {
        String startbit = tok.substring(0, startperc);
        String middlebit = System.getenv(tok.substring(startperc + 1, endperc));
        String endbit = endperc <= tok.length() ? tok.substring(endperc + 1) : ""; // substr up to end

        // integrate
        tok = startbit + middlebit + endbit;

        // reset
        startperc = -1;
        endperc   = -1;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...