Хорошо, после пяти комментариев я дошел до того, что должен просто опубликовать ответ:-)
(Предыдущие комментарии удалены)
Мне кажется, что dstdir1
и dstdir2
могут быть пустыми, так что ваша командаrsync
-синхронизируется с /
.
Чтобы предотвратить такие ошибки, измените заголовок вашего файла (завершающий пробел, необходимый после-
):
#!/bin/bash -
set -o nounset # exit on unset variables.
set -o errexit # exit on any error.
Может оказаться полезным установить shellcheck
на вашу коробку.
Я проверил его на вашем скрипте, и он жалуется на некавычки vars в строках 7, 10, 11, 13, 41 и 49. onlyonce=0
кажется неиспользуемым.
Псевдоним brc
не используется, и я бы не советовал использовать псевдонимы в сценариях оболочки. Вместо этого вы должны использовать функции.
Стефан упомянул об использовании $@
в качестве массива в простой оболочке. Вот один из способов сделать это:
#!/bin/sh
set -eux
set -- # clear cmdline params
if [ "$DEBUG" = "true" ]; then
set -- "-Xdebug" "-Xrunjdwp:transport=dt_socket,server=y,suspend=$SUSPEND,address=$DEBUG_PORT"
fi
# specify the jar file
set -- "$@" -jar /opt/someJar.jar
# add the port and profile
set -- "$@" "--server.port=${SERVER_PORT}"
set -- "$@" "--spring.profiles.active=${PROFILES}"
# and run it
java "$@"
sh
не имеет массивов (, кроме "$@"
, массива позиционных параметров ).
В:
java "${debug:-}"-jar /opt/someJar.jar "${all:-}"
java
передается только 3 аргумента (помимо самого java
).
последний будет содержать что-то вроде --server.port=1234 --spring.profiles.active=some-profile
с пробелом, в то время как вы намеревались передать два аргумента:--server.port=1234
и --spring.profiles.active=some-profile
.
скалярная(в отличие от массива)переменной, подобной $all
в sh
, может содержать только одно значение.
Вместо этого вы можете использовать массив "$@"
, как Гленн показал (, который также имеет мое предпочтение, так как смешивается с $IFS
и noglob
очень беспорядочно ), или вместо этого вы можете указать оболочке разделить содержимое переменной при расширении, установив переменную $IFS
в разделитель, и оставить расширение параметра без кавычек (после отключения подстановки, поскольку подстановка также выполняется по умолчанию для параметра без кавычек расширения ).
Для $IFS
вы хотите выбрать символ, который не может встречаться в аргументах, и если вы хотите сохранить пустые аргументы, этот символ не может быть SPC, TAB или NL (все 3 оказались в значении по умолчанию$IFS
).
Однако в вашем случае похоже, что вы хотите, чтобы пустой $serv
, например, приводил к отсутствию соответствующего аргумента, когда $serv
пуст (, в отличие от одного пустого аргумента ), поэтому пробел $IFS
, вероятно, лучшая идея. NL, вероятно, хороший выбор, так как вряд ли он будет найден в ваших аргументах здесь:
serv="--server.port=${SERVER_PORT}"
prop="--spring.profiles.active=${PROFILES}"
IFS="
" # newline character only
all="${serv:-}${IFS}${prop:-}"
set -o noglob # disable glob
java... /opt/someJar.jar $all
Вам нужно сделать что-то подобное для $debug
.
Вы можете пропустить set -o noglob
, если можете гарантировать, что ни один из аргументов не будет содержать подстановочных знаков, фигурных скобок или обратной косой черты.
Обратите внимание, что вывод xtrace
вашей оболочки немного вводит в заблуждение. Он дает представление списка аргументов, переданных команде, выводя их необработанными и разделенными символами SPC.Это означает, что из этого мы не можем отличить символы SPC, которые являются частью аргументов, от тех, которые выводятся с помощью xtrace
для разделения аргументов.
Некоторые другие оболочки более полезны здесь тем, что они заключают аргументы в кавычки, когда возникает такая неоднозначность.
Сравните вывод set -x; printf "<%s>\n" foo "bar baz"
при интерпретации несколькими разными оболочками:
$ dash -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf <%s>\n foo bar baz
<foo>
<bar baz>
$ bosh -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf <%s>\n foo bar baz
<foo>
<bar baz>
$ bash -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf '<%s>\n' foo 'bar baz'
<foo>
<bar baz>
$ ksh -c 'set -x; printf "<%s>\n" foo "bar baz"'
+ printf '<%s>\n' foo 'bar baz'
<foo>
<bar baz>
Похоже, ваш sh
относится к категории dash
/ bosh
. Посмотрите, как их вывод + printf <%s>\n foo bar baz
xtrace заставляет вас думать, что printf
передается 3 foo
, bar
, baz
аргумента, хотя на самом деле ему передаются два аргумента:foo
и bar baz
.