2011-12-11 45 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重定向到临时文件。然后等到你的进程终止,然后从文件中读取。我个人认为这个解决方案更简单,更强大。

祝你好运。