Расширение переменной Bash приводит к разрыву командной строки Java - PullRequest
1 голос
/ 22 января 2010

В последние пару дней я испытывал странную проблему при написании сценария оболочки, который выполняет Java (начиная с 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 не выполняет никаких проблем. Кроме того, когда я включаю "-server" в переменную MEM_OPTS, я получаю ошибку "нераспознанная опция".

Итак, очевидно, что с расширением переменной что-то не так. Я hexdump'd сценарий, и убедился, что в строке нет лишних символов, и убедился, что я использую окончания строки Unix. Я также воспроизвел проблему на двух разных машинах linux, хотя обе они используют одну и ту же версию ubuntu (одна 32-битная, другая 64-битная).

РЕДАКТИРОВАТЬ: я получаю тот же результат со всеми формами подстановки переменных: $ MEM_OPTS, $ {MEM_OPTS}, "$ {MEM_OPTS}"

Есть идеи?

Ответы [ 5 ]

7 голосов
/ 22 января 2010

Когда вы используете "$MEM_OPTS", вы передаете -Xms512m -Xmx1024m как один параметр.

Попробуйте вместо этого:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

Хорошее руководство по подстановке и цитированию переменных с примерами: http://tldp.org/LDP/abs/html/varsubn.html

2 голосов
/ 22 января 2010

Моя ошибка - я устанавливал IFS на "\ n" только в сценарии, в котором я использовал, functions.sh. Я никогда не сбрасывал IFS на «\ n \ t», поэтому переменные не были разделены на пробелы.

Спасибо за ответы!

2 голосов
/ 22 января 2010

думаю, что это должно работать, если кавычки вокруг $ MEM_OPTS удаляются, поскольку кавычки говорят bash передавать расширенное содержимое в качестве единственного аргумента-токена для execv ()

2 голосов
/ 22 января 2010

Я не уверен на 100% в семантике кавычек, но "$MEM_OPTS" может создать один аргумент "-Xms512m -Xmx1024m", тогда как JVM должна видеть два отдельных аргумента. Можете ли вы попробовать без кавычек?

java $SERVER $MEM_OPTS $JAVA_OPTS 
1 голос
/ 22 января 2010

Это должен быть простой вопрос изменения:

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

до:

java "$SERVER" $MEM_OPTS $JAVA_OPTS \

, чтобы параметры памяти передавались как два аргумента.

Но, поскольку вы говорите, что это не работает (?), Попробуйте следующее.

A) Создать скрипт оболочки fakejava.sh, содержащий:

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

(вам может понадобиться изменить эту первую строку, если ваш bash находится где-то еще: используйте which 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
...