2011-12-11 41 views
1

我有一個java程序應該啓動一個shell腳本。該腳本包含6個要依次執行的任務。 Java程序啓動腳本並啓動(因爲我看到日誌)。但是在10-15秒之後,即使在shell腳本中的第一個任務完成之前,執行也會停止。奇怪的是,當我在終端中啓動它時腳本運行良好。爲了避免程序在腳本執行時掛起的危險,我在一個單獨的線程中啓動它。什麼可能是一個可能的原因?從java運行shell腳本 - 沒有完成任務

Java代碼 -

try { 
      log.info("run cmd - "+optionsRun); 

      String[] cmdLine = (String[]) optionsRun.toArray(new  String[optionsRun.size()]); 

      Process process = Runtime.getRuntime().exec(cmdLine); 
      log.info("end run cmd " + this.getScriptPath()); 

//   
//   BufferedWriter writer = new BufferedWriter(new  OutputStreamWriter(process.getOutputStream())); 
//   writer.write("mypwd"); 
//   writer.flush(); 
//   writer.close(); 


      InputStream is = process.getErrorStream(); 
      String error = inputStreamToStringValue(is); 
      log.trace("Eventual error was : " + error); 

      InputStream os = process.getInputStream(); 
     String output = inputStreamToStringValue(os); 
      log.info("Eventual output was : " + output); 

      if (error!=null & error.length()>0) { 
       throw new ActionProcessingException("An error occurred when  running the script :'"+this.getScriptPath()+"' with following error message : "+error);  
      }else { 
       log.info("Script run ended successfully."); 
      } 

,而shell腳本看起來這種方式 -

#!/bin/sh 
# ./publish <path-to-publish-home-folder> <workspace_id> <start_date> <end_date> 
# ./publish <path-to-publish-home-folder> 100011 2010-01-06-12:00:00-CET  2012-01-14-19:00:00-CET 

rm -f $1/publish.log 
echo 'Start publish' >> $1/publish.log 
echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 >> $1/publish.log 

# lancement de l'export RDF du domaine 
cd $1/1-export-domain 
echo "Starting export domain with the command - ./export.sh $2" >> $1/publish.log 
./export.sh $2 

# lancement de l'export des translations du domaine 
cd $1/2-export-trans 
echo "Starting export domain(translated) with the command - ./export.sh $2" >>   $1/publish.log 
./export.sh $2 
..... 
..... 
a couple of more steps like 1 and 2 
.... 

由於提前,

+0

你在publish.log中獲得了什麼輸出? –

+0

更新:我嘗試從shell腳本中刪除資源和時間密集型任務,並執行完畢。但是,當我嘗試執行花費大量時間(和資源)的任務時,它並未完成。當shell腳本從java程序運行時是否有自動超時(或類似的情況)? – Ozyman

+0

@AndrewFielden publish.log顯示第一個任務已啓動。沒有別的。我爲每個任務都有單獨的日誌。 10或15秒後,第一項任務的記錄就停止(沒有完成任務)。我不確定是否可以從Linux日誌中找到更多信息。 – Ozyman

回答

1

我不能肯定我的猜測是問題出在你的方法inputStreamToStringValue(is)。它讀取STDERR並在讀取時阻塞。當它沒有任何要從STDERR中讀取,但過程沒有終止時,你將永遠被阻塞。

我建議你使用的ProcessBuilder:

ProcessBuilder b = new ProcessBuilder(); 
    b.redirectErrorStream(true); 

現在你可以閱讀STDIN和STDERR在一起。

如果你仍然想單獨閱讀它們,你有2個解決方案。

首先按照您現在正在做的操作,但不要在讀取時阻止,即在每次讀取調用之前調用in.available(),然後只讀取以前可用的字節數。

第二種方法是使用shell重定向。運行腳本並將其STDOUT和STDERR重定向到臨時文件。然後等到你的進程終止,然後從文件中讀取。我個人認爲這個解決方案更簡單,更強大。

祝你好運。