在Java的Runtime.exec()运行的命令中评估环境变量

时间:2010-01-19 02:20:29

标签: java environment-variables

我有一个场景,我有一个Java“代理”,它运行在几个平台上(特别是Windows,Solaris和AIX)。我想通过在我执行的命令行中使用环境变量来分解文件系统结构的差异。

据我所知,没有办法让Runtime.exec()方法来解析/评估命令String(或字符串数​​组)中引用的任何环境变量。

我知道如果push推进,我可以编写一些代码来预处理命令String(s)并手动解析环境变量(使用getEnv()等)。但是我想知道是否有一种更聪明的方法可以做到这一点,因为我确信我不是唯一一个想要这样做的人,而且我确信在“敲定”我自己的实现方面存在陷阱。

非常欢迎您的指导和建议。

修改 我想使用一些一致的表示法(如$ VAR和/或%VAR%)来引用命令字符串中的环境变量。不讨厌哪个。

修改 为了清楚起见,我希望能够执行如下命令:

perl $SCRIPT_ROOT/somePerlScript.pl args

在使用Runtime.exec()的Windows和Unix主机上

。我在配置文件中指定了一个描述要运行的作业列表的命令,它必须能够跨平台工作,因此我认为环境变量可以用来分解文件系统差异(/home/username/scripts vs { {1}})。希望有助于澄清它。

感谢。 汤姆

4 个答案:

答案 0 :(得分:6)

我想我用原来的答案误解了你的问题。如果您尝试在使用with-in Java生成的命令行上解析环境变量引用,我认为您可能需要“自己动手”。

根据操作系统的不同,有很多不同的标准可以扩展。另外,这通常是shell的功能,因此即使在相同的OS上也可能有不同的方式。实际上,标准操作系统进程激活函数(例如Unix中的exec)不执行命令行扩展。

使用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 :(得分:1)

是否有某些原因系统属性不起作用?在命令行上使用-D标志,然后可以通过System.getProperty

检索它

答案 2 :(得分:1)

正则表达式

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

是贪婪的(S+),如果是xx ${a} xx ${b} xx,它将与A} xx ${B匹配,而不是单独AB。您是否曾在cmd中使用多个变量对其进行测试?

因此,如果要替换多个变量。它应该是

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

答案 3 :(得分:0)

仅仅因为我的剪贴板中有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;
    }
}