首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bash命令在tomcat/java Runtime.getRuntime.exec()中失败,但从命令行运行

bash命令在tomcat/java Runtime.getRuntime.exec()中失败,但从命令行运行
EN

Stack Overflow用户
提问于 2016-06-13 07:51:54
回答 5查看 1.9K关注 0票数 2

我有一个tomcat,它在shell中运行一个进程,因为java中没有几个实用程序可用。--这段代码在其他机器上工作得很好,但是我的公共服务器上有一个神秘的问题。

代码语言:javascript
复制
String[] textAnalysisPipeline = {
    "/bin/sh",
    "-c",
    "/bin/cat " + inputfileLoc +
    " | tee /tmp/debug1 | " + loadJar + " " + jarOptLookupLoc + " " + optHfstLoc +
    " 2>/dev/null | " + "tail -n+5" + // get rid of the header that hfst-ol.jar produces
    " | tee /tmp/debug2 | cut -f 1-2" + // get rid of the "0.0" weights
    " | tee /tmp/debug3 | " + cgConvLoc +
    " | tee /tmp/debug4 | " + vislcg3Loc + " -g " + vislcg3DisGrammarLoc +  // disambiguate with the constraint grammar
    " | tee /tmp/debug5 > " + outputfileLoc};
log.debug("Text analysis pipeline: "+textAnalysisPipeline[2]);
Process process = Runtime.getRuntime().exec(textAnalysisPipeline);
process.waitFor();

我将字符串打印到日志,它看起来如下:(path/to/不是实际的路径)

代码语言:javascript
复制
/bin/cat /path/to/inputFile | tee /tmp/debug1 | java -jar /path/to/hfst-ol.jar /path/to/analyser.ohfst 2>/dev/null | tail -n+5 | tee /tmp/debug2 | cut -f 1-2 | tee /tmp/debug3 | /usr/local/bin/cg-conv | tee /tmp/debug4 | /path/to/vislcg3 -g /path/to/grammar.rlx | tee /tmp/debug5 > /path/to/outputFile

如果我从日志中复制这个管道并从bash命令行运行它,我将得到所需的输出,直到管道的末尾。但是,当tomcat服务器运行命令时,它会生成一个空文件。调试文件debug1debug2与预期的一样,但debug3和其后为空,这意味着管道在cut -f 1-2处失败(参见下面的更新1)。

OS - Fedora 22

java - openjdk 1.8.0_77

tomcat - 7.0.39

sh -> bash - 4.3.42(1)-release

================================================================

更新1:

这似乎不是cut的问题。我编写了一个简短的python脚本cut.py来实现与cut -f 1-2相同的功能(从每一行末尾删除'\t0.0' )

代码语言:javascript
复制
import re, sys
myRE = re.compile( r'\s+0\.0$' )
for line in sys.stdin :
    sys.stdout.write( myRE.sub( '', line ) )

使用cut.py代替cut,我也遇到了同样的问题。对于服务器debug3和更高版本来说,它是空的,但是如果我将日志中的粘贴复制到交互式shell中,那么一切都可以正常工作。

================================================================

更新2:

我还编写了一个简单的bash脚本来运行管道,这样tomcat/java只运行带有输入/输出文件名的一个参数的bash脚本。如果我从一个交互式的shell运行脚本,它可以工作,但是在tomcat中,使用shell脚本中的cutcut.py,结果没有什么不同。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-06-18 17:10:53

默认情况下,大多数系统上安装Tomcat的环境与您的用户不同。例如,它不会运行.bashrc .profile或登录脚本中的任何内容,因此在用户shell环境中设置的所有变量都是不同的。

您可以通过将env命令与两个用户进行比较来检查这一点:您的命令:您的命令,以及java程序调用它,如下所示:

代码语言:javascript
复制
String[] textAnalysisPipeline = {"/bin/sh","-c","/usr/bin/env > /tmp/env.txt"}; //or wherever the 'env' command is in your system
Process process = Runtime.getRuntime().exec(textAnalysisPipeline);
...

并将/tmp/env.txtenv执行的内容与用户进行比较.他们可能很不一样。

查找以下变量:

  • 路径
  • 克拉斯帕特
  • JAVA_HOME

我过去已经有同样的问题了。我建议采取以下办法:

  1. 对一切使用绝对路径,包括对"java“、"tee”、"tail“和libs (jar文件)的调用.你有你的命令;
  2. 更改Tomcat运行的环境配置,以到达命令中调用的所有应用程序(通常通过调用配置所有必要PATH变量的脚本(不要忘记JAVA_HOMECLASSPATH到jar文件!)。检查Startup.sh和Catalina.sh,找一个合适的地方把你的东西放进去;
  3. 更改命令,将错误输出重定向到您的消息中的/dev/null,而是重定向到您的应用程序可以编写的某个日志文件(通常/tmp/exec.log很好),这样您就可以确定shell执行问题了。我敢打赌,它会是这样的:sh: ****: command not foundError: Unable to access jarfile,或者您的应用程序的某些消息无法定位一个对象,所以您将确定您在脚本中调用的应用程序不是在PATH环境变量中,或者您没有在其中包含哪些libs .通常都是

有关此问题的其他信息,请参阅https://www.mulesoft.com/tcat/tomcat-classpath

希望这能帮上忙。

票数 3
EN

Stack Overflow用户

发布于 2016-06-15 13:43:37

这主要是一个次要的或可能的解决办法,但您的管道可以大大简化。cat无用tailcut可以用一个Awk脚本替换。

代码语言:javascript
复制
tee /tmp/debug1 <path/to/inputFile |
java -jar path/to/hfst-ol.jar path/to/analyser.ohfst 2>/dev/null |
tee /tmp/debug2 |
awk -F '\t' 'NR>5 { print $1 FS $2 }' |
tee /tmp/debug3 |
/usr/local/bin/cg-conv |
tee /tmp/debug4 |
path/to/vislcg3 -g path/to/grammar.rlx |
tee /tmp/debug5 > path/to/outputFile
票数 3
EN

Stack Overflow用户

发布于 2016-06-15 12:16:02

您可以使用ProcessBuilder。使用单字符串形式的Runtime.exec不是一种好的样式.更好的选择是使用ProcessBuilder,自己拆分参数,而不是依赖Java为您拆分它们,这是非常天真的。

代码语言:javascript
复制
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", /*...*/);
pb.redirectErrorStream(true);
Process p = pb.start();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37784355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档