开发者

Bash variable expansion causes Java commandline to break

I've been experiencing a strange issue the last couple of days while writing a shell script w开发者_开发百科hich executes Java (starting the JBoss AS). I have a variable JAVA_OPTS that I am creating, and finally passing to the 'java' command. When I hard code the values in JAVA_OPTS rather than using variable expansion, the java process executes normally. When I use variable expansion, I get errors from the java executable. Here is the relevant portions of the script:

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 &

Executing this gives the following:

Invalid initial heap size: -Xms512m -Xmx1024m
Could not create the Java virtual machine.

However when I remove the variable expansion like so:

    java "$SERVER" -Xms512m -Xmx1024m $JAVA_OPTS \

java executes no problems. As an aside, when I include "-server" in the MEM_OPTS var, I get the error "unrecognized option".

So obviously, there is something up with the variable expansion. I've hexdump'd the script, and made sure there are no extra characters in the string, and verified that I'm using Unix line endings. I've also reproduced the problem on two different linux machines, albeit both running the same version of ubuntu (one 32bit, the other 64bit).

EDIT: I get the same result with all forms of variable substitution: $MEM_OPTS, ${MEM_OPTS}, "${MEM_OPTS}"

Any ideas?


When you use "$MEM_OPTS", you're passing -Xms512m -Xmx1024m as a single option.

Try this instead:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

A good guide to variable substitution and quoting with examples: http://tldp.org/LDP/abs/html/varsubn.html


I am not 100% sure about the semantics of the quotes, but "$MEM_OPTS" may create a single argument "-Xms512m -Xmx1024m", whereas the JVM needs to see two seperate arguments. Can you try without the quotes?

java $SERVER $MEM_OPTS $JAVA_OPTS 


think it should work if the quotes around $MEM_OPTS are removed, as the quotes tell bash to pass the expanded contents as a single token argument to execv()


My mistake - I was setting IFS to "\n" only in a script I sourced in, functions.sh. I was never resetting the IFS to "\n\t ", so the variables were not split on spaces.

Thanks for the responses!


It should be a simple matter of changing:

java "$SERVER" "$MEM_OPTS" $JAVA_OPTS \

to:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

so that the memory options are passed as two arguments.

But, since you say that doesn't work (?), please try the following.

A) Create a shell script fakejava.sh containing:

#!/usr/bin/bash
echo $#
while [[ $# -ne 0 ]] ; do
    echo "    [$1]"
done

(you may need to alter that first line if your bash is somewhere else: use which bash to figure out where).

B) Set its permissions correctly:

chmod 700 fakejava.sh

C) Replace your entire java command with:

./fakejava.sh "$SERVER" $MEM_OPTS $JAVA_OPTS xx

and see how many arguments there actually are. I get:

5
    [-server]
    [-arg1]
    [-arg2]
    [none]
    [xx]

from the controlling script:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜