Bash变量扩展导致Java命令行中断

Bash变量扩展导致Java命令行中断,java,bash,size,heap,Java,Bash,Size,Heap,在过去的几天里,我在编写一个执行Java的shell脚本(启动JBoss AS)时遇到了一个奇怪的问题。我创建了一个变量JAVA_OPTS,并最终传递给“JAVA”命令。当我在JAVA_OPTS中硬编码值而不是使用变量扩展时,JAVA进程会正常执行。当我使用变量扩展时,我从java可执行文件中得到错误。以下是脚本的相关部分: SERVER="-server" MEM_OPTS="-Xms512m -Xmx1024m" case "$1" in start) java "$SERVER"

在过去的几天里,我在编写一个执行Java的shell脚本(启动JBoss AS)时遇到了一个奇怪的问题。我创建了一个变量JAVA_OPTS,并最终传递给“JAVA”命令。当我在JAVA_OPTS中硬编码值而不是使用变量扩展时,JAVA进程会正常执行。当我使用变量扩展时,我从java可执行文件中得到错误。以下是脚本的相关部分:

SERVER="-server"
MEM_OPTS="-Xms512m -Xmx1024m"

case "$1" in
start)
    java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \
    -classpath "${JBOSS_CLASSPATH}" \
    -Dorg.jboss.resolver.warning=true \
    -Dsun.rmi.dgc.client.gcInterval=3600000 \
    -Dsun.rmi.dgc.server.gcInterval=3600000 \
    -Djboss.server.name=${SERVICE_NAME} \
    -Djboss.server.base.dir=`dirname ${EC_APP_HOME}` \
    -Djboss.server.base.url=file://`dirname ${EC_APP_HOME}` \
    -Djboss.server.home.dir=${EC_APP_HOME} \
    -Djboss.server.home.url=file://${EC_APP_HOME} \
    org.jboss.Main >> out.log 2>&1 &
执行此操作将产生以下结果:

Invalid initial heap size: -Xms512m -Xmx1024m
Could not create the Java virtual machine.
但是,当我删除变量展开式时,如下所示:

    java "$SERVER" -Xms512m -Xmx1024m $JAVA_OPTS \
java执行没有问题。另一方面,当我在MEM_OPTS变量中包含“-server”时,会出现错误“unrecogned option”

很明显,变量展开式有些问题。我已经对脚本进行了hexdump,并确保字符串中没有多余的字符,并验证了我使用的是Unix行结尾。我也在两台不同的linux机器上重现了这个问题,尽管它们都运行相同版本的ubuntu(一台32位,另一台64位)

编辑:所有形式的变量替换都得到相同的结果:$MEM_OPTS,${MEM_OPTS},${MEM_OPTS}”

有什么想法吗?

当您使用
“$MEM_OPTS”
时,您将
-Xms512m-Xmx1024m
作为单个选项传递

请尝试以下方法:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \
变量替换和引用示例的良好指南:

当您使用
“$MEM_OPTS”
时,您将
-Xms512m-Xmx1024m作为单个选项传递

请尝试以下方法:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

一个很好的变量替换和引用示例指南:

我不是100%确定引号的语义,但是
“$MEM_OPTS”
可能会创建一个参数
“-Xms512m-Xmx1024m”
,而JVM需要看到两个独立的参数。你能不用引号试试吗

java $SERVER $MEM_OPTS $JAVA_OPTS 

我不能100%确定引号的语义,但是
“$MEM_OPTS”
可能会创建一个参数
“-Xms512m-Xmx1024m”
,而JVM需要看到两个独立的参数。你能不用引号试试吗

java $SERVER $MEM_OPTS $JAVA_OPTS 

如果$MEM_OPTS周围的引号被删除,它应该工作,因为引号告诉bash将扩展内容作为单个令牌参数传递给execv()

如果$MEM_OPTS周围的引号被删除,它应该工作,因为引号告诉bash将扩展内容作为单个令牌参数传递给execv()这应该是一个简单的改变:

java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \
致:

因此,内存选项作为两个参数传递

但是,既然你说这不管用(?),请尝试下面的方法

A) 创建一个shell脚本
fakejava.sh
包含:

#!/usr/bin/bash
echo $#
while [[ $# -ne 0 ]] ; do
    echo "    [$1]"
done
(如果您的
bash
在其他地方,您可能需要更改第一行:使用
哪个bash
确定位置)

B) 正确设置其权限:

chmod 700 fakejava.sh
C) 将整个
java
命令替换为:

./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx
看看到底有多少论点。我得到:

5
    [-server]
    [-arg1]
    [-arg2]
    [none]
    [xx]
从控制脚本:

#!/usr/bin/bash
JAVA_OPTS="none"
SERVER="-server"
MEM_OPTS="-arg1 -arg2"
./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx

这应该是一个简单的改变:

java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \
致:

因此,内存选项作为两个参数传递

但是,既然你说这不管用(?),请尝试下面的方法

A) 创建一个shell脚本
fakejava.sh
包含:

#!/usr/bin/bash
echo $#
while [[ $# -ne 0 ]] ; do
    echo "    [$1]"
done
(如果您的
bash
在其他地方,您可能需要更改第一行:使用
哪个bash
确定位置)

B) 正确设置其权限:

chmod 700 fakejava.sh
C) 将整个
java
命令替换为:

./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx
看看到底有多少论点。我得到:

5
    [-server]
    [-arg1]
    [-arg2]
    [none]
    [xx]
从控制脚本:

#!/usr/bin/bash
JAVA_OPTS="none"
SERVER="-server"
MEM_OPTS="-arg1 -arg2"
./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx

我的错误-我只是在我源于functions.sh的脚本中将IFS设置为“\n”。我从未将IFS重置为“\n\t”,因此变量不会在空格上拆分


谢谢你的回复

我的错误-我只是在我源于functions.sh的脚本中将IFS设置为“\n”。我从未将IFS重置为“\n\t”,因此变量不会在空格上拆分


谢谢你的回复

谢谢你的回复。我也得到了同样的结果,没有引号。我更新了原来的问题,澄清了这一点。谢谢你的回答。我也得到了同样的结果,没有引号。我更新了原来的问题,澄清了这一点。我发现了我的错误——没有重置IFS变量。这项测试将有助于证明这一点。谢谢@purecharger,您可能应该接受自己的答案(因为这是实际的解决方案),并投票选出所有有帮助的人。我想你必须等24小时才能接受自己的答案。干杯,很高兴你解决了。是的,还需要10个小时。非常感谢。我发现了我的错误-没有重置IFS变量。这项测试将有助于证明这一点。谢谢@purecharger,您可能应该接受自己的答案(因为这是实际的解决方案),并投票选出所有有帮助的人。我想你必须等24小时才能接受自己的答案。干杯,很高兴你解决了。是的,还需要10个小时。谢谢大家!+1因为这是“实际”解决方案,尽管其他解决方案有帮助。+1因为这是“实际”解决方案,尽管其他解决方案有帮助。