2013-04-03 50 views
1

我想用java在特定位置運行腳本。運行良好,如果我手動運行該腳本:Runtime.exec沒有運行但沒有例外

 /export/home/trace.sh param1 param2 param3 param4 

這是我的代碼從Java運行腳本:

 try { 

     Runtime runtime = Runtime.getRuntime(); 
     Process proc = null; 
     System.out.println("starting search"); 
     proc = runtime.exec(pathServer + "/trace.sh " + fullDate + " " + fullDateTo + " " + mA.substring(2) + " " + mB.substring(2)); 
     InputStream inputstream   = proc.getInputStream(); 
     InputStreamReader inputstreamreader = new InputStreamReader(inputstream); 
     BufferedReader bufferedreader   = new BufferedReader(inputstreamreader); 
     System.out.println("end search " + System.currentTimeMillis()); 
     } 
    catch (Exception e) 
     { 
     System.out.println(e.toString()); 
     e.printStackTrace(); 
     } 

如果腳本運行時,它會產生「txt.dat」在指定位置。但是沒有生成「txt.dat」。我試圖找出異常是什麼,但沒有例外。

我的代碼已經正確嗎?我如何知道它是否正在處理腳本?我怎樣才能捕捉到在這個過程中發生的任何異常?謝謝。


更新2

我添加一些代碼來打印getInputStreamgetErrorStream。 對於getInputStream,我什麼也沒得到,這意味着它是空的。 對於getErrorStream,我得到這個結果

  Host key verification failed 

我仍然不知道這是什麼錯誤表示。

的Java應用程序在服務器B.運行

一般情況下,我想調用(在服務器B)的腳本將ssh到服務器A和運行在服務器A.它會生成文本其他腳本。 DAT,然後SFTP發佈到服務器B.當手動運行它,txt.dat成功生成並傳送到服務器B.


更新3

感謝所有幫助和建議。事實證明,我的Java應用程序在不同的用戶下運行。當我手動運行它時,我使用了另一個用戶。所以,我已經將服務器B的主機密鑰添加到服務器A.現在它已成功運行。

+1

你能打印pathServer的值嗎? –

+1

你檢查了在控制檯上手動運行的命令嗎? ,它工作正常嗎? –

+0

@Sudhanshu:pathServer是「/ export/home」。我已經驗證過它。 – angel

回答

1

您可以調試或打印Process.getErrorStreamProcess.getInputStream以檢查子過程報告的錯誤。

我的猜測是你需要調用/bin/sh作爲主程序並將腳本作爲參數傳遞,但我不確定。我知道你必須在Windows上這樣做。

+0

您好Tim,thx的建議。我終於用getErrorStream捕捉異常,並說:「主機密鑰驗證失敗。」你知道這是什麼意思嗎?我運行的腳本是爲生成的文本,然後sftp到其他服務器。它工作正常,如果我手動運行它 – angel

1

Runtime.exec如果您的命令失敗,則不會拋出異常。

您使用process.exitValue()得到執行結果。

此外,您還可以從代碼中創建的process.getInputStream()中獲取腳本輸出,但不會從某些原因讀取。在腳本中放入一些echo語句進行調試。

2

您可以對代碼進行相當多的改進。

  1. 使用ProcessBuilder來創建您的過程,而不是Runtime。它爲您提供更多的選擇和更大的控制權
  2. 通過你的命令的每個組件作爲一個單獨的字符串建設者
  3. 完全消耗你的輸出和錯誤流
  4. 等待的過程中實際完成

類似這樣的:

try { 
    ProcessBuilder builder = new ProcessBuilder() 
      .command("/export/home/trace.sh", param1, param2, param3, param4); 
    builder.redirectErrorStream(true); 

    System.out.println("starting search"); 
    Process proc = builder.start(); 
    final BufferedReader bufferedreader = new BufferedReader(
      new InputStreamReader(proc.getInputStream())); 
    new Thread() { 
     @Override 
     public void run() { 

      try { 
       String line = null; 
       StringBuffer buffer = new StringBuffer(2048); 
       while ((line = bufferedreader.readLine()) != null) { 
        buffer.append(line); 
       } 
      } catch (final IOException ioe) { 
       ioe.printStackTrace(); 
      } 
      // Do something with process output, if needed 
     } 
    }.start(); 

    proc.waitFor(); 
    System.out.println("end search " + System.currentTimeMillis()); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 
+0

嗨知覺,THX的建議。我嘗試運行你的代碼,但我得到這個異常'java.io.IOException:無法運行程序「/export/home/trace.sh 20130401 20130402 62813 62815」:錯誤= 2,沒有這樣的文件或目錄'我不明白爲什麼它說沒有這樣的文件或目錄,我甚至運行完全相同的命令併成功。 – angel

+0

腳本是否嘗試創建/訪問臨時目錄?您的Java程序可能沒有足夠的權限運行,並且在通過它調用跟蹤程序時無法創建相同的目錄。 – Perception

+0

不,它不是創建/訪問臨時目錄。但該腳本將ssh到其他服務器。這是相關的嗎?爲什麼當我使用runtime.exec時錯誤是不同的?當我使用runtime.exec和捕捉異常,它說'主機密鑰驗證失敗' – angel