Java选项-XX:OnOutOfMemoryError在bash脚本中通过exec调用时不起作用



我有一个java应用程序,我想在它遇到OutOfMemoryException时运行一个脚本

这个很好:

$ java -server -XX:OnOutOfMemoryError="./oom_script %p" TestOOMClass

不幸的是,我的应用程序在生产中是由bash脚本运行的。该脚本可以归结为:

cmd='java -server  -XX:OnOutOfMemoryError="./oom_script %p"  TestOOMClass'
##does a lot of checking and cmd building here
exec -a app  ${cmd}

当像这样运行时,java从不尊重双引号,并认为%p是类。我该如何预防呢?

由于您的程序是作为shell脚本运行的,因此我建议将以下内容作为shell脚本的第一行,在shebang之后:

set -xv

然后,在crontab中,将2>&1放在命令行末尾,这样STDERR和STDOUT就合并了。Crontab通常会将命令的STDOUT通过电子邮件发送给root,这样您就可以看到输出结果了。如果没有,则在crontab中的命令末尾追加以下内容:

> /somedir/output.$$ 2>&1

确保somedir存在,在crontab运行命令后,您将看到详细和调试输出。shell脚本中的每一行都将在执行之前显示——既按照编写的显示,也按照shell实际解释的显示。

set -xv在调试任何销售脚本时变得非常有用。在cronjob和在登录下运行的脚本之间可能会涉及各种环境问题。您甚至可能会发现shell问题。例如,crontab通常在Bourne shell中执行shell脚本,您可能将Bash或Kornshell作为默认shell。无论它是什么,当您打开详细/调试模式时,您通常会很快发现问题。

您甚至不必对整个脚本执行此操作。您可以将set -xv放在脚本中的任何位置,以打开详细/调试模式,并将set +xv关闭。

我可以提出一些高尚的建议(使用引号,不要假设环境因素,在命令行加上"bash -c"前缀以确保您使用的是正确的shell,等等),但这将是猜测可能出错的地方。为了真正调试这个问题,我需要查看机器,了解操作系统,查看整个shell脚本,并了解整个环境。而且,我要做的第一件事是在shell脚本中添加set -xv

引号和转义是一门艺术。我建议你在调用exec之前添加echo ${cmd},这样你就可以看到它是什么样子的。

我建议使用

cmd='java -server  -XX:OnOutOfMemoryError=\"./oom_script %p\"  TestOOMClass'

相反(未测试)。您需要它在回显时看起来像"

我建议的另一种选择(绕过问题,而不是真正解决它)是运行和bash脚本并访问$PPID:

   PPID   The process ID of the shell's parent.  This variable is readonly.

然后用该ID终止进程(请记住,这是一个未经测试的建议)

最新更新