Если у Вас есть окна PC, можно попробовать YUMI, который, по-моему, является лучшим инструментом для создания загрузочного usb с мультипараметром загрузки.
Я сожалею, что признал, но работы YUMI только к окнам.
Первое замечание, что args
покажет два аргумента, даже если вы дадите ему только один:
$ args "abc def"
1 : <abc> <def>
Чтобы он корректно отображался, удвойте-Необходимо добавить:
$ function args() { printf "%d :" $#; printf " <%s> " "$@"; echo; }
$ args "abc def"
1 : <abc def>
Однако, все еще есть проблемы с определением JAVA_OPTS
. Обратите внимание:
$ args $JAVA_OPTS
3 : <-Xmx1g> <-XX:OnError='/path/to/a/script.sh> <%p'>
Это происходит потому, что когда $JAVA_OPTS
появляется в командной строке, оболочка будет делать расщепление слов по содержимому JAVA_OPTS, но она не уважает и не обрабатывает содержащиеся в ней кавычки.
Для данного типа приложения гораздо лучше использовать JAVA_OPTS, определенный как bash-массив:
$ JAVA_OPTS="-Xmx1g"
$ JAVA_OPTS=("$JAVA_OPTS" "-XX:OnError=/path/to/a/script.sh %p")
$ args "${JAVA_OPTS[@]}"
2 : <-Xmx1g> <-XX:OnError=/path/to/a/script.sh %p>
Кстати, при работе с массивами, удобный способ посмотреть, что в них находится, -побъявить -p
:
$ declare -p JAVA_OPTS
declare -a JAVA_OPTS='([0]="-Xmx1g" [1]="-XX:OnError=/path/to/a/script.sh %p")'
Можно передать парсеру оболочки другой проход:
var="'-Xmx1g' \"-XX:OnError='/path/to/a/script.sh %p'\""
eval "echo $var"
-Xmx1g -XX:OnError='/path/to/a/script.sh %p'
Но массив, вероятно, лучше:
set -- '-Xmx1g "-XX:OnError='/path/to/a/script.sh %p'"
echo "item count $#"
for i do
echo "item#$((n=$n+1)): $i"
done
echo "$@"
item count 2
item#1: -Xmx1g
item#2: -XX:OnError='/path/to/a/script.sh %p'
-Xmx1g -XX:OnError='/path/to/a/script.sh %p'
Хотя они не обязательно взаимоисключающие:
eval "set $var"
item count 2
item#1: -Xmx1g
item#2: -XX:OnError='/path/to/a/script.sh %p'
-Xmx1g -XX:OnError='/path/to/a/script.sh %p'
Изнутри функции - как args()
- если бы вы захотели объединить два аргумента, вы бы просто сбросили его массив аргументов:
args() {
[ $# -gt 2 ] && {
a=$1; shift
set -- "$a" "$*"
} ; printf "%d :" $#
printf " <%s> " "$@"
echo
}
Но это уже обратная работа. Если вы хотите, чтобы эти переменные были в массиве:
args() {
printf "%d :" $#
printf " <%s> " "$@"
echo
}
args "$JAVA_OPTS" "-XX:OnError='/path/to/a/script.sh %p'"
или в текущем массиве оболочки...
set -- "$JAVA_OPTS" "-XX:OnError='/path/to/a/script.sh %p'"
Все формы выводят:
2 : <-Xmx1g> <-XX:OnError='/path/to/a/script.sh %p'>
А если в какой-то момент вы захотите добавить в массив:
set -- "$@" "some ne
w arg"
args "$@"
3 : <-Xmx1g> <-XX:OnError='/path/to/a/script.sh %p'> <some ne
w arg>
Массив идет вместе с оболочкой. Вы должны использовать его.
Вы должны использовать массив вместо:
declare -a JAVA_OPTS
JAVA_OPTS+=("-Xmx1g")
JAVA_OPTS+=("-XX:OnError='/path/to/a/script.sh %p'")
args "${JAVA_OPTS[@]}"
Как только что-то попадает в строку, вы не можете выбрать, какие пробелы будут использоваться для разделения слов, но с помощью массива вы можете решить, когда вы их вставляете и когда вы их снова вытаскиваете. Вы также захотите процитировать $@
внутри args
, иначе он сломается.
Если вы действительно должны определить его с помощью одной строки, вы можете использовать другой символ для разделения элементов и сбросить IFS
:
JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS|-XX:OnError='/path/to/a/script.sh %p'")
IFS="|"
args $JAVA_OPTS
также сделает правильный выбор в этом случае, хотя он довольно хрупкий. Как всегда, вы захотите сохранить и сбросить IFS
, или же внести изменения только в подоболочку.
JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS|-XX:OnError='/path/to/a/script.sh %p'")
IFS="|"
args $JAVA_OPTS
:
JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS|-XX:OnError='/path/to/a/script.sh %p'")
IFS="|"
args $JAVA_OPTS
::
JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS|-XX:OnError='/path/to/a/script.sh %p'")
IFS="|"
args $JAVA_OPTS
:
JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS|-XX:OnError='/path/to/a/script.sh %p'")
IFS="|"
args $JAVA_OPTS
.