2013-07-23 156 views
2

我需要運行兩個命令Linux中使用這樣的Java代碼:連續運行的Linux命令與Java運行時EXEC

Runtime rt = Runtime.getRuntime(); 


      Process pr=rt.exec("su - test"); 
      String line=null; 
      BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream())); 

      while((line=input.readLine()) != null) { 

       System.out.println(line); 
      } 
      pr = rt.exec("whoami"); 
      input = new BufferedReader(new InputStreamReader(pr.getInputStream())); 

      line=null; 

      while((line=input.readLine()) != null) { 
       System.out.println(line); 
      }    
      int exitVal = pr.waitFor(); 
      System.out.println("Exited with error code "+exitVal);    
     } catch(Exception e) { 
      System.out.println(e.toString()); 
      e.printStackTrace(); 
     } 

問題是第二命令(「WHOAMI」)的輸出不顯示當前用戶在第一個命令(「su - 測試」)上使用! 請問這個代碼有什麼問題嗎?

+0

try語句丟失。請始終發佈一個可運行的示例。 – reindeer

回答

2

Javadoc for Runtime.exec()指出:

執行指定的字符串命令在單獨的進程

每次通過exec()執行命令時,它都會在一個單獨的子進程中執行。這也意味着返回時su的效果立即消失,這就是爲什麼whoami命令將在另一個子進程中執行,同樣使用最初啓動程序的用戶。

su test -c whoami 

會給你你想要的結果。

+0

並且在這種情況下的測試是suppossed爲用戶帳戶名稱?請你澄清一下吧! –

4

在一般情況下,您需要在shell中運行命令。事情是這樣的:

Process pr = rt.exec(new String[]{"/bin/sh", "-c", "cd /tmp ; ls"}); 

但在這種情況下,這不會工作,因爲su本身就是創造一個互動的子shell。你可以這樣做,但:

Process pr = rt.exec(new String[]{"su", "-c", "whoami", "-", "test"}); 

Process pr = rt.exec(new String[]{"su", "test", "-c", "whoami"}); 

另一種方法是使用sudo,而不是su;例如

Process pr = rt.exec(new String[]{"sudo", "-u", "test", "whoami"}); 

注意:當沒有以上的實際需要這一點,組裝「命令行」作爲一個字符串數組,而不是讓exec做了「解析」是個好主意。 (問題是,exec小號分流不明白shell引用。)

+0

我得到一個錯誤與所有上述說法java.io.IOException:不能運行程序「新」:錯誤= 2,沒有這樣的文件或目錄 – qre0ct

+0

我認爲你的代碼必須大大不同我的代碼才能得到*那*錯誤信息。我的代碼中沒有''新的''字符串。 –