Я умоляю вас, шаг от простого расширения оболочки в cp
командной строке - оболочка расширение имеет все виды гм . «Интересных» угловые случаи (нежелательных рекурсию , вызванные и .., пробела, непечатаемые вещи, жесткие ссылки, символические ссылки, и и т. д.) Используйте find
вместо этого (он входит в findutils
пакет, если он у вас не установлен - что было бы странно, все дистрибутивы устанавливают его по умолчанию):
find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;
Пошаговое объяснение:
-H
приведет к тому, что find
не будет следовать символическим ссылкам (кроме случаев, когда фактическое имя каталога верхнего уровня, которое вы дали, является символической ссылкой; это будет следовать.)
/path/to/toplevel/dir/
Очевидно, что он должен быть заменен вами путем к каталогу, в котором находятся файлы настроек и каталоги, резервные копии которых вы хотите создать.
-maxdepth 1
остановит find
рекурсивный спуск в любые каталоги, имя которых начинается с точки. Нам не нужно это повторять, cp
мы сделаем это за нас, нам просто нужны имена на этом уровне.
-name '.*'
говорит, find
что мы хотим, чтобы все имена начинались с точки. Это не будет работать правильно, если установлена переменная окружения POSIXLY_CORRECT
, но редко (если вообще когда-либо). Это первое условие соответствия, которое мы указали до сих пор.
a \( ....... \)
является и сопровождается более сложным условием в скобках (я использовал ..... для его замены, это объяснено ниже.) Нам нужно избегать скобок, так как иначе они будут (неправильно) интерпретироваться оболочкой, отсюда и обратный слеш перед ними,
-type d -o -type f -o -type l
три условия с или между ними. -type d
сопоставляет каталоги, -type f
сопоставляет обычные файлы и -type l
сопоставляет символические ссылки. Вы можете выбрать то, что вы хотите - например, если вы не хотите делать резервные копии каталогов настроек, опустите -type d
( -o
очевидно, и справа за ним).
-exec ..... \;
говорит find
выполнить команду каждый раз, когда встречается совпадение. Конец команды отмечен точкой с запятой, которую мы снова должны экранировать обратной косой чертой, чтобы избежать интерпретации оболочки. В этой командной строке вам нужно использовать, {}
где вы хотите, чтобы имя встречающегося в данный момент совпадения заканчивалось. Так как оболочки могут также неверно истолковывать фигурные скобки, вы должны поместить их в апострофы, как в '{}'
. В этом случае мы хотим выполнить команду cp -a '{}' /path/to/destination/dir/
(-a означает архив, который повторяется в подкаталогах, копирует символические ссылки в виде ссылок и сохраняет разрешения и расширенные атрибуты и /path/to/destination/dir/
, очевидно, является именем целевого каталога - замените его.)
Итак, на простом английском языке эта find
командная строка говорит следующее:
Начните с / path / to / toplevel / dir /. Не спускайтесь ни в какие подкаталоги. Найти все каталоги, файлы и символические ссылки, чье имя начинается с точки. Для каждого из найденных объектов скопируйте его в / path / to / destination / dir / сохраняя природу, разрешения и расширенные атрибуты.
-r
и-R
?