Рекурсивное копирование скрытых файлов - 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вызоветfindnot 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