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

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

cp -R .* directory

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

6 ответов

Решение

Моим любимым ходом режиссеров вообще было:

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

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

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

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

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

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

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

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

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

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

I implore you, step away from plain shell expansion on the cp command line - shell expansion has all sorts of ahem "interesting" corner cases (unwanted recursion caused by. and.., spaces, non-printable stuff, hardlinks, symbolic links, and so on.) Use find instead (it comes in the findutils package, in case you don't have it installed - which would be weird, all distributions install it by default):

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/ \;

Step by step explanation:

  • -H вызовет find not to follow symlinks (except if the actual toplevel directory name you gave it is a symlink; that it will follow.)
  • /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

Другие вопросы по тегам