Ответ Стивена Рауха описывает проблему. У меня есть другое решение.
Но сначала: почему вы помещаете такую длинную команду в переменную? Просто чтобы вы могли его распечатать? Почему бы просто не использовать параметр оболочки verbose (show команды)?
set -v (your_command) set + v
Опция x
(трассировка выполнения) похожа; попробуйте выше с set -x
и set +x
увидеть разницу. Если вам нравятся оба, вы можете комбинировать их с set -vx
и set +vx
.
Довольно плохая идея построить строку из последовательности слов, разделенных пробелами, а затем попытаться разбить ее на части, чтобы восстановить исходные слова компонента. Вы столкнулись с одной из ловушек. Другой - теоретическая возможность того, что имя файла может содержать пробелы; из командной строки было бы невозможно сказать, cat foo bar baz
что foo bar
это одно имя файла, а baz
другое (и вы видели, что построение строки также cat "foo bar" baz
не работает должным образом). Эти и другие вопросы обсуждаются здесь:
Кроме того, вам не нужно printf
просто объединять строки.
Если вы действительно хотите собрать командную строку в хранилище и используете bash, вы можете использовать переменную массива, например:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption --include="/etc" --include="/var/log" --include="/var/db" --include="/var/www" --include="/home" --exclude="**" / scp://duplicity@myhost.com:22//home/duplicity/backups/"$VPSNAME")
Обратите внимание, что я положил $LOG_FILE
и $VPSNAME
в кавычки. Вы всегда должны заключать в кавычки все ссылки на переменные оболочки, если у вас нет веских причин не делать этого, и вы уверены, что знаете, что делаете. Но Стивен прав: вы на самом деле не нужно цитировать постоянные строки, как "/etc"
, "/var/log"
, "/var/db"
и так далее. (Но, конечно, вы действительно должны процитировать "**"
, потому что *
это специальный символ.)
Для удобства чтения вы можете разбить вышеперечисленное на несколько строк. Обратите внимание, что первая строка говорит, =
а последующие строки говорят +=
, потому что они добавляют к тому, что было раньше:
DulicityCMD=(duplicity --log-file "$LOG_FILE" --progress --no-encryption) DulicityCMD+=(--include="/etc" --include="/var/log" --include="/var/db") DulicityCMD+=(--include="/var/www" --include="/home" --exclude="**") DulicityCMD+=(/ scp://duplicity@myhost.com:22//home/duplicity/backups/"$VPSNAME")
Тогда вы можете сделать
printf "% s \ n" "$ " (для печати команды) "$ " (для выполнения команды)
или используйте sudo "$"
, если вам нужно. Смотрите bash (1) для получения дополнительной информации о синтаксисе bash, и мой ответ здесь, чтобы узнать больше об этой технике массива.