gpt4 book ai didi

java - 在 -XX :OnOutOfMemoryError using shell script gives: Unrecognized option: -9 上重新启动进程

转载 作者:太空宇宙 更新时间:2023-11-04 08:58:11 25 4
gpt4 key购买 nike

我正在尝试在 OOME 发生时重新启动进程。 Java 二进制文件使用两个 shell 脚本启动,其中一个导入另一个。我无法控制第一个,但可以根据需要修改第二个。这是我正在尝试做的原型(prototype):

第一个shell脚本test.sh:

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

echo $JAVA_OPTS
java $JAVA_OPTS $es_params TestMemory

第二个shell脚本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\""

一般它所做的是在 test1.sh 中构建 JAVA_OPTS 然后用于运行 Java 二进制文件,它只是将 PID 写入 pidfile 然后创建 OOME。

执行过程中出现问题,java无法理解什么是参数,什么是要运行的类。我认为这可能是引用的问题,我尝试了不同的方法来转义 JAVA_OPTS,但没有任何结果。我要么得到:

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 文件中并使用它代替变量,它也能正常工作。

运行 set -x 后,我看到 shell 将每个空格字符修改为 ' ' - 在两边添加 '。转义不会产生任何结果。知道如何避免这种情况吗?所以最后的表扬是:

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

更新

我可以成功运行简化命令

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

但这似乎是一个普遍的问题,我猜 shell 只是讨厌变量中的空格:

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

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

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

我尝试了不同的选择来逃脱

最佳答案

这是一个 shell 问题。根据证据,我会说其中一个 ; 字符......可能还有一些为什么空格......当你不希望/需要这种情况发生时,shell会解释它.

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


It seems shell translates every single space to ' ',

不完全是。单引号由 shell 插入到您从 set -x 获得的输出中。它们只是指示参数边界在哪里。它们实际上并不存在......而且它们肯定不会传递给 java 命令。

Any idea how to [a]void it?

您需要做的是从您尝试执行的(最终)命令开始......

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

... 并向后工作,以便 shell 变量、扩展和转义为您提供所需的东西。

另一件需要注意的事情是:

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

可能行不通。 kill $(cat test.pid) 命令使用 shell 语法并需要 shell 功能来插入 PID 文件的内容。我怀疑 JVM 是否会知道如何处理它。 (或者更准确地说。它会按照你的字面意思告诉它去做,但这不会是你想要的......)

如果您确实需要在运行重启命令时插入 pid 文件内容,就像您似乎正在尝试做的那样,那么建议将重启命令转换为独立的 shell 脚本,并设置文件模式,使其可执行。开始工作会更简单、更容易。

作为一条一般性建议,对 shell 脚本过于聪明并不是一个好主意。变量扩展和命令解析的确切语义相当棘手,如果您尝试在多个级别执行此操作,很容易让自己感到困惑。

关于java - 在 -XX :OnOutOfMemoryError using shell script gives: Unrecognized option: -9 上重新启动进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26684777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com