在-XX上重新启动进程:OnOutOfMemoryError使用shell脚本给出:无法识别的选项:-9 [英] Restarting process on -XX:OnOutOfMemoryError using shell script gives: Unrecognized option: -9

查看:695
本文介绍了在-XX上重新启动进程:OnOutOfMemoryError使用shell脚本给出:无法识别的选项:-9的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当OOME发生时,我正在尝试重启进程。 Java二进制是使用两个shell脚本启动的,其中一个脚本导入其他脚本。我没有任何控制的第一个,但可以修改我想要的第二个。
这是我正在尝试做的一个原型:

I'm trying to restart process when OOME happens. Java binary is launched using two shell scripts, one of them imports other. I don't have any control of the first one but can modify the second one as I want. This is a prototype what I'm trying to do:

第一个shell脚本test.sh:

First shell script test.sh:

#!/bin/sh
JAVA_OPTS="$JAVA_OPTS -Xmx10m"
. test1.sh

echo $JAVA_OPTS
java $JAVA_OPTS $es_params TestMemory

第二个shell脚本test1.sh:

Second shell script test1.sh:

#!/bin/sh

pidfile="test.pid"
touch $pidfile
params="$parms -Dpidfile=$pidfile"

kill_command="kill -9 \$(cat $pidfile)"

dir=$( cd $(dirname $0) ; pwd -P )
path="$dir/$(basename $0)"

start_command="$path $@"

restart_command="$kill_command;sleep 2;$start_command"

JAVA_OPTS="$JAVA_OPTS -XX:OnOutOfMemoryError=\"$restart_command\""

通常它的作用是JAVA_OPTS在test1.sh内部构建,然后用于运行Java二进制,它只是在pidfile中写入PID,然后创建OOME。

Generally what it does is JAVA_OPTS is constructed inside test1.sh and then used to run Java binary, which just writes PID in pidfile and then creates OOME.

执行过程中发生问题,java不能理解什么是参数,什么是要运行的类。我认为这可能是一个引用的问题,我尝试了不同的方式来逃避JAVA_OPTS,但没有任何结果。我要得到:

Problem happens during execution, java can't understand what is a parameter and what is a class to run. I think it might be a problem of quoting, I tried different ways to escape JAVA_OPTS, but without any result. I'm either getting:

Unrecognized option: -9
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Error: Could not find or load main class "-XX:OnOutOfMemoryError=kill

如果我只需要一个值JAVA_OPTS,并将其手动放在test.sh中,它完美运行
任何想法如何更改test1.sh使其工作?我想我几乎尝试了双重和单一的方法引用,但没有任何成功,而且如果我将restart_command放在restart.sh文件中,并使用它而不是变量,它的工作正常。

If I just take a value of JAVA_OPTS and put it manually in test.sh it runs perfectly. Any ideas how can I change test1.sh to make it work? I think I tried almost every possible way of putting double and single quotes, but without any success. Also if I put restart_command in restart.sh file and use it instead of the variable, it works fine.

运行set -x I后看到shell将每个单个空格字符修改为 - 添加在两边,Escaping没有给出任何结果,任何想法如何避免这个?所以最后的推荐是:

After running set -x I saw that shell modifies every single space character to ' ' - adds ' on both sides. Escaping doesn't gives any result. Any idea how to avoid this? So final commend is:

+ java -Xmx10m '"-XX:OnOutOfMemoryError=kill' '$(cat' 'test.pid);sleep' '2;/Users/davidt/test/TestMemory/bin/test.sh' '")' -Des.pidfile=test.pid TestMemory



更新



我c一个运行简化命令成功

Update

I can run simplified command successfully

java "-XX:OnOutOfMemoryError=echo 'Ups'" $es_params TestMemory

但是似乎一般的问题,shell只是讨厌空格变成我想:

But it seems a general problem, shell just hates spaces into variables I guess:

JAVA_OPTS="\"-XX:OnOutOfMemoryError=echo 'Ups'\""
set -x
java $JAVA_OPTS TestMemory

此脚本失败,最后一行解释为:

This script fails and the last line is interpreted as:

java '"-XX:OnOutOfMemoryError=echo' ''\''Ups'\''"' TestMemory 

我尝试了不同的选项来转义

I tried different options to escape

推荐答案

这是一个shell问题。根据证据,我会说,你不要在shell中解释一个; 想要/需要这样做。

This is a shell problem. Based on the evidence, I'd say that one of the ; characters ... and possibly some why space ... is being interpretted by the shell when you don't want / need this to happen.

如果在运行命令之前在shell中运行 set -x 尝试启动JVM,您将看到正在使用的实际命令。

If you run set -x in the shell before running the command that is trying to start the JVM, you will see the actual command that is being used.


似乎shell将每个空格翻译成',

It seems shell translates every single space to ' ',

不完全是。单引号由shell插入到您从 set -x 获取的输出中。他们只是指出参数边界在哪里。他们不是真的在那里...他们肯定没有被传递给 java 命令。

Not exactly. The single quotes are inserted by the shell into the output you are getting from set -x. They simply indicating where the argument boundaries are. They are not really there ... and they are certainly NOT being passed to the java command.


任何想法如何[a]无效?

Any idea how to [a]void it?

您需要做的是从(最终)命令你正在尝试执行...

What you need to do is start from the (final) command that you are trying execute ...

java -Xmx10m -XX:OnOutOfMemoryError="kill NNNN;sleep 2;/Users/davidt/test/TestMemory/bin/test.sh" -Des.pidfile=test.pid TestMemory

...并向后工作,所以shell变量,扩展和转义给你你需要的。

... and work backwards, so that the shell variables, expansions and escaping give you what you need.

另外要注意的是这个:

java -Xmx10m -XX:OnOutOfMemoryError="kill $(cat test.pid); ..."

可能不会工作。 kill $(cat test.pid)命令正在使用shell语法,需要shell功能来内插PID文件的内容。我怀疑JVM将会知道该怎么做。 (或者更准确地说,它会做你从字面上告诉它做的,但这不会是你想要的...)

probably won't work. The kill $(cat test.pid) command is using shell syntax and requires shell functionality to interpolate the contents of the PID file. I doubt that the JVM is going to know what to do with that. (Or more accurately. It will do what you have literally told it to do, but that will not be what you want ...)

如果你真的需要插值当您似乎尝试执行重新启动命令运行时,pid文件内容,建议将restart命令转换为独立的shell脚本,并设置文件模式,以便它是可执行文件。这将更简单,更容易得到工作。

If you really need to interpolate the pid file content when the restart command is run as you appear to be trying to do, then suggest that turn the restart command into a free-standing shell script, and set the file mode so that it is executable. It will be simpler and a lot easier to get working.

作为一般的建议,使用shell脚本是一个太过聪明的坏主意。变量扩展和命令解析的确切语义是相当棘手的,很容易使自己真的困惑...如果你想在多个层次上这样做。

As a general piece of advice, is is a bad idea to be too clever with shell scripts. The exact semantics of variable expansion and command parsing are rather tricky, and it is easy to get yourself really confused ... if you are trying to do this at multiple levels.

这篇关于在-XX上重新启动进程:OnOutOfMemoryError使用shell脚本给出:无法识别的选项:-9的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆