2017-01-16 7 views
1

Я написал Баш скрипт со следующим:Rsync и цитирует

SRC="dist_serv:$HOME/www/" 
DEST="$HOME/www/" 
OPTIONS="--exclude 'file.php'" 
rsync -Cavz --delete $OPTIONS $SRC $DEST 

Rsync не удается, и я не могу понять, почему, несмотря на то, что, как представляется, связано с $ OPTIONS переменной (она работает, когда я удаляю Это). Я попытался убежать из пространства с обратной косой чертой (среди многих других вещей), но это не сработало. Сообщение об ошибке:

rsync: mkdir "/home/xxx/~/public_html/" failed: No such file or directory (2) 

Я попытался процитировать переменный, которая бросает другую ошибку («неизвестный параметр» на моем переменном $ OPTIONS):

rsync: --exclude 'xxx': unknown option 
rsync error: syntax or usage error (code 1) at main.c(1422) [client=3.0.6] 

ответ

0

Вы не должны ставить перед $ имен переменных при присвоении им значений. SRC - переменная, $SRC - это значение, которое оно расширяет.

Кроме того, ~ не распространяется на путь вашего домашнего каталога, когда вы помещаете его в кавычки. Как правило, лучше использовать $HOME в сценариях, так как эта переменная ведет себя как переменная, которую ~ не делает.

Всегда процитировать переменных разложения:

rsync -Cavz --delete "$OPTIONS" "$SRC" "$DEST" 

, если нет какой-то причине не (там очень редко бывает). В противном случае оболочка будет выполнять разбиение слов на них. @fred

Пользователь указывает на то, что вы не можете использовать двойные кавычки $OPTIONS (в в комментариях ниже), но это должно быть хорошо, если вы используете OPTIONS='--exclude="file.php"' (обратите внимание на =).

+0

переменная OPTIONS не может быть заключено в кавычки, потому что она содержит два слова, и цитирование предотвратит их от раскола при интерпретации команды (они будут рассматриваться как одна строка). В этом случае не цитирование OPTIONS будет работать, потому что оно не содержит пробелов, но это не общее решение. – Fred

+0

да, конечно, переменное назначение! Редактирование моего вопроса ... – mrtnmgs

+1

@immicile Если бы вы могли также упомянуть точное сообщение об ошибке, которое вы получаете от 'rsync' в вопросе, это очень помогло бы! – Kusalananda

0

Одним из методов, который я считаю неоценимым, является использование позиционных параметров, облегчающих работу со списком параметров.

Когда вы помещаете опции внутри переменной (например, переменную OPTIONS), вам нужно найти способ включения кавычек внутри значения и опускать кавычки при ссылке на переменную. Он работает, но вы всегда остаетесь в стороне от сложного отладки.

Вместо этого попробуйте следующее.

set -- -Cavz --delete 
set -- "[email protected]" --exclude "file.php" 
set -- "[email protected]" "dist_serv:~/www/" 
set -- "[email protected]" "~/www/" 
rsync "[email protected]" 

Конечно, в этом случае, все могло бы быть на той же линии, но и во многих случаях будет условные выражения, так что, например, вы можете пропустить данную опцию, или выбрать разностные файлы для работы с. Самое приятное, что вы всегда используете ту же цитату, которую будете использовать в одной командной строке, все благодаря магии "[email protected]", которая позволяет не ссылаться (или не указывать) какую-либо конкретную переменную.

Если фактические позиционные параметры мешают, вы можете поместить их в переменные или создать функцию, чтобы изолировать контекст, который позволяет не трогать их там, где они имеют значение.

Я использую этот трюк все время, и я прекратил вытягивать волосы из-за цитирования, вызывающего проблемы внутри значений, которые я передаю как параметр командам.

Аналогичный результат можно достичь, используя массив.

declare -a ARGUMENTS=() 
ARGUMENTS=(-Cavz --delete) 
ARGUMENTS+=(--exclude "file.php") 
ARGUMENTS+=("dist_serv:~/www/") 
ARGUMENTS+=("~/www/") 
rsync "${ARGUMENTS[@]}" 
+0

Это хороший обходной путь, но мой скрипт уже использует позиционные параметры, и они будут перезаписаны. – mrtnmgs

+0

Я добавил решение на основе массива, которое дает похожие результаты без использования позиционных параметров. – Fred