Как скопировать с помощью cp, чтобы включить скрытые файлы и скрытые каталоги и их содержимое?


392

Как я могу сделать cp -rкопию абсолютно всех файлов и каталогов в каталоге

Требования:

  • Включите скрытые файлы и скрытые каталоги.
  • Будьте одной командой с флагом, чтобы включить выше.
  • Не нужно полагаться на сопоставление с образцом вообще.

Мой некрасивый, но работающий хак это:

cp -r /etc/skel/* /home/user
cp -r /etc/skel/.[^.]* /home/user

Как я могу сделать все это в одной команде без сопоставления с образцом? Какой флаг мне нужно использовать?


1
Здесь больше ответов, хотя они выглядят не так хорошо; serverfault.com/questions/3154/…
— Роэль Ван де Паар

Пожалуйста, Eleven81, рассмотрите возможность изменения принятого ответа на ответ, заданный @bruno pereira, потому что он избегает создания новой папки. Если нет, то пусть этот комментарий будет предупреждением для новых читателей, чтобы проверить также другой (наиболее проголосовавший) ответ. Tx.
— Доктор Беко

Ответы:


265

Не указывайте файлы:

cp -r /etc/skel /home/user

(Обратите внимание, что он /home/userне должен уже существовать, иначе он будет создан /home/user/skel.)


61
Можно ли использовать нечто подобное, если /home/user/skel оно существует?
— bradley.ayers

@ bradley.ayers Я думаю, что можно скопировать во временный подкаталог, а затем переместить их на верхний уровень (так как перемещение на одном диске происходит быстро). Менее чем идеал, но короче, чем другие решения для меня.
— Халил Озгюр

7
@ bradley.ayers Ответ Бруно, приведенный ниже, отвечает на ваш вопрос
— Марк

1
Это решение не сработало для меня. Он не копировал скрытые файлы. Я использую CentOS релиз 6.5. Решение @ Бруно сработало.
— Technext

2
В Ubuntu / Debian это помещает каталог 'skel' в целевой каталог, а не рекурсивные файлы внутри skel. Используйте -T(без цели) ниже для правильного использования. ( -rTдля
— рекурсии

467

Допустим, вы создали новую папку (или собираетесь ее создать) и хотите скопировать в нее файлы после ее создания.

mkdir /home/<new_user>
cp -r /etc/skel/. /home/<new_user>

Это позволит рекурсивно скопировать все файлы / папки из /etc/skelуже существующей папки, созданной в первой строке.


5
Если я не понял неправильно, это не скопировало скрытые / точечные файлы.
— Халил Озгюр

34
Хорошо работает для меня. Обратите внимание, что "." имеет решающее значение для его работы.
— Mark

12
Это работает, но почему? Не могу найти ссылку на это в руководстве.
— Жюльен Палар

5
Я думаю, что это работает, потому что обычно это создает новую папку с именем последней папки в первом аргументе. Однако, так как это имя ., это поведение потребует от него создания уже существующего каталога, поэтому он просто пропускает этот шаг.
— Zenexer

28
@Technext По умолчанию глобализация в bash не включает имена файлов, начинающиеся с a ., чтобы изменить то, что вам нужно использовать shopt -s dotglobкоманду перед тем, как включать эти файлы. Таким образом *, по умолчанию вы запрашиваете рекурсивное копирование всех файлов из этого каталога, который можно расширить с помощью *(который по умолчанию не содержит скрытых файлов). В то время как на другом конце .вы используете cp для рекурсивного копирования всего из «этого каталога».
— Бруно Перейра

80

Правильный способ сделать это - использовать эту -T (--no-target-directory)опцию и рекурсивно копировать папки (без конечных слешей, звездочек и т. Д.), То есть:

cp -rT /etc/skel /home/user

Это скопирует содержимое /etc/skelв /home/user(включая скрытые файлы), создав папку, /home/userесли она не существует; однако эта -Tопция предотвращает /etc/skelкопирование содержимого в новую папку, /home/user/skelесли папка /home/userсуществует.


3
Правильный ответ. +1
— бшеа

это был действительно правильный ответ
— Gaetan

это ЛУЧШИЙ ответ из группы; это единственный, который решает проблему, не усложняя ее
— ZaxLofful

точно работает, чтобы скопировать, как ожидалось
— Chetabahana

Очень нравится, когда вы используете правильный флаг cmd для одного случая.
— Тран Триет

66

bashсама имеет хорошее решение, оно имеет shell option, Вы можете cp, mvи так далее .:

shopt -s dotglob # for considering dot files (turn on dot files)

а также

shopt -u dotglob # for don't considering dot files (turn off dot files)

Выше решение является стандартом bash

НОТА:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set

2
Это полезно, когда вы хотите скопировать только содержимое, не создавая новый каталог в месте назначения. Особенно, когда пункт назначения является точкой монтирования.
— kaszynek

3
Это действительно лучший ответ, и он доходит до сути вопроса ..
— Стивен

7
Это setoptдля Zsh, на случай, если кому-то еще интересно.
— Пэт

25

Используйте rsync:

rsync -rtv source_folder/ destination_folder/


Лучший вариант для меня, хотя я использую --progress, чтобы получить больше отзывов обо всем процессе.
— Edenshaw

5

rsync это хорошо, но другой выбор:

cp -a src/ dst/

Из основной справки:

   -a, --archive
          same as -dR --preserve=all

   -d     same as --no-dereference --preserve=links

   -R, -r, --recursive
          copy directories recursively

Я всегда использовал cp -r. Спасибо за упоминание cp -a
— Пинаки Мукерджи

4

Если ваш исходный и целевой каталог имеют одно и то же имя, даже если целевой каталог существует, вы можете просто набрать:

cp -R /etc/skel /home/

Это скопирует каталог / etc / skel в / home /, включая скрытые файлы и каталоги.

В конце концов, вы можете скопировать каталог и переименовать его в одну строку:

cp -R /etc/skel /home/ && mv /home/skel /home/user

Или вы можете просто использовать cp -r /etc/skel /home/userдля переименования skelв user...
— Дэвид

Это верно, только если / home / user еще не существует.
— Габриэль Хаутлок

4

Вы можете использовать rsync.

rsync -aP ./from/dir/ /some/other/directory/

Вы даже можете скопировать через SSH

rsync -aP ./from/dir/ username@remotehost:/some/other/directory/

Существуют различные флаги, которые вы можете использовать: -a, --archive # archive (-rlptgoD)

-r, --recursive
-l, --links      # copy symlinks as links
-p, --perms      # preserve permissions
-t, --times      # preserve times
-g, --group      # preserve group
-o, --owner      # preserve owner
-D               # --devices --specials

--delete         # Delete extra files

You may want to add the -P option to your command.

--partial        # By default, rsync will delete any partially transferred file if the transfer is interrupted. In some circumstances it is more desirable to keep partially transferred files. Using the --partial option tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.

-P               # The -P option is equivalent to --partial --progress.   Its  purpose  is to make it much easier to specify these two options for a long transfer that may be interrupted.

Страница руководства Rsync


4

Самый простой способ:

cp -r /etc/skel/{.,}* /home/user

Выражение {.,}*включает все файлы и каталоги (также начинающиеся с точки).

Если вы не хотите использовать вышеприведенное выражение, вы можете использовать cpсвойство, которое позволяет указывать несколько источников для одной целевой папки:

cp -r /etc/skel/* /etc/skel/.* /home/user

1
в этом случае будут пропущены файлы типа ..anythingили ...anythingдр. - stackoverflow.com/a/31438355/2351568 содержит правильное регулярное выражение для этой проблемы. || но в любом случае использование shopt -s dotglob- все еще лучшее решение!
— DJCrashdummy

@DJCrashdummy, к сожалению, я не понимаю, почему вы написали свое внимание. В конце концов, мое решение учитывает случаи, о которых вы пишете. С уважением
— simhumileco

извините неправильный текст! - проблема с вашим ответом в том, что он также будет учитывать .и ..(что эквивалентно текущей и содержащей ее папке). || но все же ответ в ссылке объясняет это дальше и предоставляет решение.
— DJCrashdummy

2

Обратите внимание, что есть хитрость командной строки (работает, по крайней мере, в sh , bash и ksh ): просто добавьте суффикс к каталогу from . Это выльет содержимое каталога from в каталог to (по иронии судьбы я впервые узнал об этом приеме при использовании rsync ).

Пример:

/tmp$ mkdir test_dir1
/tmp$ cd test_dir1/
/tmp/test_dir1$ touch aa
/tmp/test_dir1$ touch .bb
/tmp/test_dir1$ cd ..
/tmp$ mkdir test_dir2

/tmp$ cp -r test_dir1/* test_dir2
/tmp$ ls -1a test_dir2
.
..
aa

/tmp$ cp -r test_dir1/ test_dir2
/tmp$ ls -1a test_dir2
.
..
.bb
aa

2

Я пришел сюда с Googled для решения той же проблемы, а потом понял, что это легко сделать с помощью find. Преимущество это не зависит от оболочки или специальных утилит, которые могут быть не установлены.

find /etc/skel/ -mindepth 1 -exec cp -r {} /home/username/ \;

Я попробовал трюк с косой чертой, но это не сработало для меня.


2

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

yes | cp -rvp /source/directory /destination/directory/

yesпредназначен для автоматической перезаписи файлов назначения, rрекурсивного, vмногословного, pсохранения разрешений.

Обратите внимание, что исходный путь не заканчивается на/ (поэтому все файлы / каталог и. Файлы скопированы)

Каталог назначения заканчивается тем,/ что мы помещаем содержимое исходной папки в место назначения в целом.


1

Я видел, что cp не всегда копирует скрытые файлы, и если вам нужна команда, которая работает на всех диалектах Linux / Unix, вы должны попробовать использовать:

cd /etc/skel
find | cpio -pdumv /home/user

-2

Начиная как минимум с K3b 2.0.3, при добавлении каталога в проект появляется окно вопроса, в котором спрашивается, хотите ли вы включить скрытые файлы ... также появляется вопрос, который нужно задать о включении ссылки. Хорошие вещи!


«всплывающее окно с вопросом» - для команды оболочки (CLI)?
— Скотт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.