从java运行shell脚本-不';我不能完成任务

从java运行shell脚本-不';我不能完成任务,java,shell,runtime,Java,Shell,Runtime,我有一个java程序,应该启动一个shell脚本。该脚本包含6个按顺序执行的任务。java程序启动脚本并启动它(正如我看到的日志)。但是在10-15秒之后,执行停止,甚至在shell脚本中的第一个任务完成之前。奇怪的是,当我在终端中启动脚本时,它运行良好。为了避免脚本执行时程序挂起的风险,我在单独的线程中启动它。可能的原因是什么 Java代码- try { log.info("run cmd - "+optionsRun); String[

我有一个java程序,应该启动一个shell脚本。该脚本包含6个按顺序执行的任务。java程序启动脚本并启动它(正如我看到的日志)。但是在10-15秒之后,执行停止,甚至在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
....
#/垃圾箱/垃圾箱
#/出版
#/发布100011 2010-01-06-12:00:00-CET 2012-01-14-19:00:00-CET
rm-f$1/publish.log
echo“开始发布”>>$1/publish.log
echo$0$1$2$3$4$5$6$7$8$9>>$1/publish.log
#多梅因出口区兰斯门特酒店
cd$1/1-导出域
echo“使用命令-./export.sh$2>>$1/publish.log启动导出域”
./export.sh$2
#多梅因翻译出口酒店
cd$1/2-出口-运输
echo“使用命令-./export.sh$2>>$1/publish.log启动导出域(已翻译)”
./export.sh$2
.....
.....
还有两个步骤,如1和2
....

提前谢谢,

我不确定,但我会推荐两个可能帮助您解决问题的链接

第一个是关于
Runtime.exec()
的非常古老的一个:

第二个是关于
ProcessBuilder
,它是一个新类,用于替换
Runtime.exec()


我不能确定我猜问题出在您的方法
InputStreamToString值(is)
中。它读取STDERR,并在读取时阻塞。当它没有从STDERR读取任何内容,但进程尚未终止时,您将永远被阻止

我建议您使用ProcessBuilder:

    ProcessBuilder b = new ProcessBuilder();
    b.redirectErrorStream(true);
现在您可以一起阅读STDIN和STDERR

如果你仍然想单独阅读,你有两种解决方案

首先按照现在的操作进行,但不要在读取时被阻塞,即在每次调用read之前调用.available(),然后只读以前可用的字节数

第二种方法是使用shell重定向。运行脚本并将其STDOUT和STDERR重定向到临时文件。然后等待进程终止,然后读取文件。我个人认为这个解决方案更简单、更健壮


祝你好运。

publish.log中有什么输出?更新:我尝试从shell脚本中删除资源和时间密集型任务,执行顺利。但是,当我试图执行花费大量时间(和资源)的任务时,它无法完成。当shell脚本从java程序运行时,是否有任何自动超时(或类似情况?@AndrewFielden publish.log显示第一个任务已启动。没有别的了。我对每个任务都有单独的日志。10秒或15秒后,第一个任务的日志记录将停止(任务未完成)。我不确定是否可以从linux日志中找到更多信息。如果没有看到export.sh的内容,很难回答。它做什么?export.sh是一个启动程序的简单命令行。它看起来像是java-jar-Xmx512M-Xms512M-export-6.7.1-SNAPSHOT-onejar.jar-workspace$1-output RDF-filename trans