Назад | Перейти на главную страницу

Рекурсивное копирование скрытых файлов - Linux

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

cp -R .* directory

но он признает . и .. а также рекурсивно копирует все не скрытые файлы. Есть ли способ заставить cp игнорировать . и ..?

Практически каждый раз это можно решить с помощью:

cp -R .[a-zA-Z0-9]* directory

Довольно необычно иметь скрытый файл, который не начинается с одного из этих символов.

Доступны другие совпадения с образцом (.??*, .[^.]*) - см. комментарии

Моим любимым способом перемещения каталогов в целом было:

tar cvf - . | (cd /dest/dir; tar xvf -)

который преобразует текущий каталог в стандартный вывод, а затем направляет его в подоболочку, которая сначала выполняет компакт-диск в целевой каталог перед распаковкой stdin. Простой, прямой, расширяемый - подумайте, что произойдет, если вы замените () на ssh на другой машине. Или, чтобы ответить на ваш вопрос, вы можете сделать:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)

Вы могли бы использовать rsync.

rsync -a ./ /some/other/directory/

который скопирует содержимое текущего каталога (включая точечные файлы, но не включая ..)

Умоляю вас, отойдите от простого расширения оболочки на 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 / с сохранением характера, разрешений и расширенных атрибутов.

Я всегда использовал. ?? *, чтобы найти скрытые файлы, не получая "." и "..". Хотя он может пропустить ".a" или что-то в этом роде, но у меня их никогда не было.

Здесь гораздо лучшие ответы; https://superuser.com/questions/61611/how-to-copy-with-cp-to-include-hidden-files-and-hidden-directories-and-their-con

Он описывает, например, использование shopt для нативного решения bash.