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

392

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

Требования:

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

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

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

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

eleven81
источник
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существует.

TechnocratiK
источник
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/

user1084282
источник
Лучший вариант для меня, хотя я использую --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
Wink Saville
источник
Я всегда использовал 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

RoshP
источник
4

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

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

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

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

cp -r /etc/skel/* /etc/skel/.* /home/user
simhumileco
источник
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)?
Скотт