2010-01-19 116 views
3

我有一個在幾個平臺(特別是Windows,Solaris & AIX)上運行的Java「代理程序」。我想通過在我執行的命令行中使用環境變量來分析文件系統結構中的差異。Java Runtime.exec運行的命令中的環境變量評估()

據我所知,沒有辦法讓Runtime.exec()方法來解析/評估命令String(或String數組)中引用的任何環境變量。

我知道,如果推動推動我可以寫一些代碼來預處理命令字符串和手動解決環境變量(使用getEnv()等)。不過,我想知道是否有更聰明的方法來做到這一點,因爲我確信我不是唯一想做這件事的人,我確信在「敲」我自己的實施方面存在缺陷。

我們非常歡迎您的指導和建議。

編輯: 我想使用一些一致的符號(如$ VAR和/或%VAR%)在命令字符串中引用環境變量。沒有融化哪個。

編輯: 要清楚,我想能夠執行一個命令,例如:

perl $SCRIPT_ROOT/somePerlScript.pl args

在Windows和UNIX主機使用Runtime.exec()。我在配置文件中指定了描述要運行的作業列表的命令,並且它必須能夠跨平臺工作,因此我認爲環境變量將有助於分析文件系統差異(/home/username/scripts vs C:\foo\scripts)。希望有助於澄清它。

謝謝。 Tom

+0

你是如何解決這些問題的?在傳遞給'Runtime.exec()'的命令字符串中使用'$ VAR'的Unix shell方法? – 2010-01-19 02:40:53

+0

@凱文 - 是的。理想的情況下。 – 2010-01-19 02:51:34

回答

6

我想我誤解了你的問題和我的原始答案。如果您正嘗試解析您在Java中使用生成的命令行上的環境變量引用,我認爲您可能需要「自行開發」。

根據操作系統的不同,這些擴展方式有很多不同的標準。另外,這通常是shell的一個功能,所以即使在同一個操作系統上也可能有不同的方式。事實上,標準的操作系統進程激活功能(例如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(); 
    } 
+0

乾杯 - 我懷疑這將是我最終做的事情。我確信我不是第一個嘗試它的人。也許我使用錯誤的術語來搜索。也感謝代碼。 – 2010-01-19 09:28:58

+0

我會用'sb.append(cmd,lastMatchEnd,m.start())'替換'sb.append(cmd.substring(lastMatchEnd,m.start()))'以避免字符串複製。與另外兩次調用'sb.append(... substring(...))'類似。 – 2016-03-04 06:53:03

1

是否有某些原因系統屬性不起作用?在命令行上使用-D標誌,然後你可以通過System.getProperty來檢索它

+0

嘿史蒂夫 - 我不知道這將如何幫助?也許我的問題不清楚。我會盡力澄清它。 – 2010-01-19 02:53:20

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; 
    } 
} 
1

正則表達式

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

是貪婪(S+)和在xx ${a} xx ${b} xx情況下它將匹配A} xx ${B代替seperately AB。你有沒有在cmd中用多個變量測試它?

所以如果有多個變量需要替換。它應該是

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