2012-10-26 45 views
2

我想檢查發行版名稱,但是我遇到了使用bash執行命令的問題。爲什麼此代碼正常工作並打印文件夾內容Java:Runtime.exec獲取Linux發行版名稱

String cmd[] = {"ls","-a"}; 
Runtime run = Runtime.getRuntime(); 
try { 
    Process proc = run.exec(cmd); 
    BufferedReader read=new BufferedReader(new InputStreamReader(proc.getInputStream())); 
    while(read.ready()) { 
     System.out.println(read.readLine()); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

但是cmd[] = {"cat","/etc/*-release"};不是嗎?它根本不打印任何東西,既不是錯誤也不是發行版。 OFC。它在終端工作。那有什麼問題?

回答

4

它在Bash中的工作原理是Bash將/etc/*-release識別爲glob並執行必要的文件名擴展。 Process不這樣做;它只是用你指定的確切參數調用cat。 (換句話說,你正在運行bash命令cat '/etc/*-release'的等價物。)

一種選擇,我想,是實際調用Bash和讓它處理爲你:

String cmd[] = { "bash", "-c", "cat /etc/*-release" }; 

,但我認爲使用Java文件系統API在/etc中搜索名稱以-release結尾的文件並正常讀取該文件的內容會更有意義。 (參見the Javadoc for java.io.Filethe Javadoc for java.io.FileReader。)

0

嘗試這種情況:

String[] cmd = { 
    "/bin/sh", "-c", "cat /etc/*-release" }; 

    try { 
     Process p = Runtime.getRuntime().exec(cmd); 
     BufferedReader bri = new BufferedReader(new InputStreamReader(
       p.getInputStream())); 

     String line = ""; 
     while ((line = bri.readLine()) != null) { 
      System.out.println(line); 
     } 
    } catch (IOException e) { 

     e.printStackTrace(); 
    } 
0

Runtime.exec不會調用殼(例如bash)的,而是直接啓動過程。當你在bash中鍵入ls /etc/*-release時,bash本身負責將*擴展爲與模式匹配的所有文件名。所以當bash調用ls命令時,ls會將實際的文件名視爲參數。另一方面,當你的java代碼調用ls命令時,ls會看到實際的字符串「/ etc/* - release」,這是一個不存在的文件。

最簡單的修復方法是通過/ etc/lsb-release。更好的解決方案是調用lsb_release -c