Учитывая этот кусок Баш:
PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}
Эхо показывает строку PARMS, как и ожидалось, ошибки не отображаются, но rsync работает тихо, как если бы опции, добавленные + =, не существовали. Тем не менее, это работает как ожидалось:
PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}
Наверное, я что-то напортачил с кавычками bash (с ними всегда были проблемы), но не совсем уверен, что и почему параметры игнорируются, даже если строка, кажется, построена правильно.
echo "$PARMS"
иrsync "${PARMS}"
...bash
версией 4.2.25 без каких-либо изменений.Ответы:
Есть разница между:
и
В первом случае одинарные кавычки находятся внутри самих кавычек, поэтому они буквально присутствуют в подстановочном тексте, заданном в
rsync
качестве аргументов.rsync
получает аргумент, значение которого--exclude='.git'
. Во втором случае одинарные кавычки интерпретируются оболочкой во время их написания, потому что они не находятся внутри самих кавычек и ихrsync
можно увидеть--exclude=.git
.В этом случае вам не нужны одинарные кавычки -
.git
это совершенно корректное слово оболочки само по себе, без специальных символов, поэтому вы можете использовать его буквально в команде.Лучше всего для такого рода вещей использовать массив :
Это создает вашу команду как отдельные слова, с любой цитатой, которую вы хотите интерпретировать во время написания строки массива.
"${PARMS[@]}"
расширяется до каждой записи в массиве как отдельный аргумент, даже если в самом аргументе есть специальные символы или пробелы, поэтому онrsync
видит то, что вы написали, как вы это имели в виду.источник
bash
выполнено разделение слов после${PARMS}
расширения. Таким образом, единственная цитата также была интерпретирована оболочкой.\
,'
и"
. , Что не является результатом одной из вышеуказанных расширений удаляются» «вышеупомянутые расширения» включает в себя расширение параметров, которое выполняет расширение${PARMS}
.IFS
(как правило, пробела), вам не нужно их заключать в кавычки. Если это так, то вам не повезло, если вы не взломали что-то вместе с нимeval
- это, в общем-то, небольшая ошибка, и массивы - правильный способ справиться с этим.В дополнение к ответу @Michael Homer вы можете использовать
bash
функцию eval :источник
eval
.