файл сценария и командная строка: rsync и --exclude - PullRequest
8 голосов
/ 11 мая 2009

У меня есть простой тестовый скрипт bash, который выглядит так:

#!/bin/bash

cmd="rsync -rv --exclude '*~' ./dir ./new"
$cmd # execute command

Когда я запускаю скрипт, он также копирует файлы, оканчивающиеся на ~, хотя я хотел исключить их. Когда я запускаю ту же самую команду rsync прямо из командной строки, она работает! Кто-нибудь знает почему и как заставить работать bash-скрипт?

Кстати, я знаю, что могу работать и с --exclude-from, но я все равно хочу знать, как это работает.

Ответы [ 3 ]

6 голосов
/ 11 мая 2009

Попробуйте eval :

#!/bin/bash

cmd="rsync -rv --exclude '*~' ./dir ./new"
eval $cmd # execute command
5 голосов
/ 12 мая 2009

Проблема не в том, что вы запускаете его в сценарии, а в том, что вы помещаете команду в переменную, а затем запускаете расширенную переменную. А поскольку расширение переменной происходит после того, как удаление кавычек уже выполнено, одинарные кавычки вокруг шаблона исключения никогда не удаляются ... и поэтому rsync завершает работу, исключая файлы с именами, начинающимися с 'и заканчивающимися на ~'. Чтобы это исправить, просто удалите кавычки вокруг шаблона (все это уже в двойных кавычках, поэтому они не нужны):

#!/bin/bash

cmd="rsync -rv --exclude *~ ./dir ./new"
$cmd # execute command

... говоря о том, почему вы помещаете команду в переменную перед ее выполнением? В общем, это хороший способ сделать код более запутанным, чем это должно быть, и вызвать странности разбора (некоторые даже страннее, чем это). Как насчет:

#!/bin/bash

rsync -rv --exclude '*~' ./dir ./new
0 голосов
/ 11 мая 2009

Вы можете использовать простой --eclude '~' as (согласно справочной странице):

  • если шаблон начинается с /, то он привязывается к определенному месту в иерархия файлов, в противном случае это сопоставляется с концом путь к файлу. Это похоже на ведущий ^ в регулярных выражениях. Таким образом, "/ Foo" будет соответствовать имени "Foo" в любом «корень передачи» (для глобальное правило) или в файле слияния каталог (для правила для каждого каталога). Неквалифицированный "foo" будет соответствовать имя "foo" в любом месте дерева потому что алгоритм применяется рекурсивно сверху вниз; Это ведет себя так, как будто каждый компонент пути получает поворот быть концом имя файла. Даже незанятый «sub / foo» будет соответствовать в любой точке иерархия, в которой было найдено "foo" в каталоге с именем «sub». Увидеть раздел на якорь ВКЛЮЧИТЬ / ИСКЛЮЧИТЬ УЗОРЫ для полного обсуждение того, как указать шаблон что соответствует корню передачи.
  • если шаблон оканчивается на /, то он будет соответствовать только каталогу, а не обычный файл, символическая ссылка или устройство.
  • rsync выбирает между простым совпадением строк и подстановочным знаком соответствие путем проверки, если шаблон содержит один из этих трех символов подстановки символы: '*', '?' и '['.
  • a '*' соответствует любому компоненту пути, но останавливается на слешах.
  • используйте '**' для сопоставления чего угодно, включая косую черту.
...