Comment copier avec cp pour inclure des fichiers cachés et des répertoires cachés et leur contenu?

393

Comment faire pour cp -rcopier absolument tous les fichiers et répertoires d'un répertoire

Exigences:

  • Inclure les fichiers cachés et les répertoires cachés.
  • Soyez une seule commande avec un drapeau pour inclure ce qui précède.
  • Pas besoin de compter sur la correspondance de modèle du tout.

Mon hack, mais qui travaille, c'est:

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

Comment puis-je faire tout cela en une seule commande sans correspondance de modèle? Quel drapeau dois-je utiliser?

onze81
la source
1
Plus de réponses ici, même si elles ne semblent pas aussi bonnes; serverfault.com/questions/3154/…
Roel Van de Paar
Eleven81, envisagez de remplacer la réponse acceptée par celle donnée par @bruno pereira, car cela évite de créer un nouveau dossier. Sinon, laissez ce commentaire être un avertissement pour que les nouveaux lecteurs vérifient également l'autre réponse (la plus votée). Tx.
Dr Beco

Réponses:

266

Ne spécifiez pas les fichiers:

cp -r /etc/skel /home/user

(Notez que cela /home/userne doit pas déjà exister, sinon cela va créer /home/user/skel.)

Randy Orrison
la source
62
Est - il possible d'utiliser quelque chose de similaire si n'existe? /home/user/skel
bradley.ayers
@ bradley.ayers Je pense que l'on pourrait copier dans un sous-répertoire temporaire puis les déplacer au niveau supérieur (car le déplacement dans le même lecteur est rapide). Moins qu'idéal, mais plus court que d'autres solutions pour moi.
Halil Özgür
7
@ bradley.ayers La réponse de Bruno ci-dessous répond à votre question
Mark
1
Cette solution n'a pas fonctionné pour moi. Il n'a pas copié les fichiers cachés. J'utilise la version 6.5 de CentOS. @ La solution de Bruno a fait l'affaire.
Technext
2
Sous ubuntu / debian, cela place le répertoire 'skel' dans le répertoire cible et non les fichiers récursifs dans skel. Utilisez -T(pas de cible) comme indiqué ci-dessous pour une utilisation correcte. ( -rTpour récursif)
bshea
467

Disons que vous avez créé le nouveau dossier (ou allez en créer un) et que vous souhaitez y copier les fichiers une fois le dossier créé.

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

Cela copiera tous les fichiers / dossiers de manière récursive de /etc/skeldans le dossier existant déjà créé sur la première ligne.

Bruno Pereira
la source
5
Si je ne me suis pas trompé, cela ne copiait pas les fichiers cachés.
Halil Özgür
34
Fonctionne bien pour moi. Notez que le '.' est essentiel à son fonctionnement.
Marc
12
Cela fonctionne, mais pourquoi? Impossible de trouver une référence à cela dans le manuel.
Julien Palard le
5
Je pense que cela fonctionne car normalement, cela créerait un nouveau dossier avec le nom du dernier dossier dans le premier argument. Toutefois, puisque ce nom est ., ce comportement nécessiterait la création d'un répertoire déjà existant. Il ignore donc cette étape.
Zenexer
28
@Technext La bascule par défaut dans bash n'inclut pas les noms de fichiers commençant par un ., pour changer, vous devez utiliser la shopt -s dotglobcommande avant de pouvoir inclure ces fichiers. Donc, avec *, par défaut, vous demandez de copier tous les fichiers de ce répertoire qui peuvent être développés de manière récursive *(qui n'inclut pas les fichiers cachés par défaut). De l’autre côté, .vous utilisez cp pour copier récursivement tout ce qui se trouve dans "ce répertoire".
Bruno Pereira
81

Pour ce faire, utilisez l' -T (--no-target-directory)option et copiez les dossiers de manière récursive (sans les barres obliques, astérisques, etc.), c'est-à-dire:

cp -rT /etc/skel /home/user

Cela copiera le contenu de /etc/skeldans /home/user(y compris les fichiers cachés), créant le dossier /home/users'il n'existe pas; Toutefois, cette -Toption empêche la /etc/skelcopie du contenu de dans un nouveau dossier /home/user/skelsi celui-ci /home/userexiste.

Technocratie
la source
3
Bonne réponse. +1
bshea
c'était en effet exactement la bonne réponse
Gaétan
C’est la MEILLEURE réponse du groupe; c'est le seul qui résout le problème sans le compliquer
ZaxLofful
fonctionne exactement pour copier comme prévu
Chetabahana
Aimez-le lorsque vous utilisez le bon drapeau cmd pour le même cas.
Tran Triet
67

bashlui-même a une bonne solution, il a un shell option, vous pouvez cp, mvet ainsi de suite .:

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

et

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

La solution ci-dessus est standard bash

REMARQUE:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set
Golfe Persique
la source
2
C'est utile lorsque vous souhaitez copier uniquement du contenu sans créer de nouveau répertoire dans la destination. Surtout quand le répertoire de destination est le point de montage.
Kaszynek
3
C'est vraiment la meilleure réponse et va au coeur de la question ..
Stephen
7
C'est setoptpour zsh, au cas où quelqu'un d'autre se le demanderait.
Pat
25

Utilisez rsync:

rsync -rtv source_folder/ destination_folder/

utilisateur1084282
la source
La meilleure option pour moi, bien que j'utilise --progress pour avoir plus de retours sur l'ensemble du processus.
Edenshaw le
5

rsync c'est bien, mais un autre choix:

cp -a src/ dst/

De l'aide principale:

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

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

   -R, -r, --recursive
          copy directories recursively
Clin d'oeil Saville
la source
J'ai toujours utilisé cp -r. Merci d'avoir mentionné cp -a
Pinaki Mukherjee le
4

Si votre répertoire source et votre répertoire cible ont le même nom, même s'il existe, vous pouvez simplement taper:

cp -R /etc/skel /home/

Cela copiera le répertoire / etc / skel dans / home /, y compris les fichiers et répertoires cachés.

Vous pouvez éventuellement copier le répertoire et le renommer en une seule ligne:

cp -R /etc/skel /home/ && mv /home/skel /home/user
Gabriel Hautclocq
la source
Ou vous pourriez simplement utiliser cp -r /etc/skel /home/userpour renommer skelen user...
David, le
C'est vrai, seulement si / home / user n'existe pas encore.
Gabriel Hautclocq
4

Vous pouvez utiliser rsync.

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

Vous pouvez même copier sur ssh

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

Vous pouvez utiliser différents indicateurs: -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.

Page de manuel de Rsync

RoshP
la source
4

Le moyen le plus simple est:

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

L'expression {.,}*inclut tous les fichiers et répertoires (commençant également par un point).

Si vous ne souhaitez pas utiliser l'expression ci-dessus, vous pouvez utiliser la cppropriété, qui permet de spécifier plusieurs sources pour un dossier cible:

cp -r /etc/skel/* /etc/skel/.* /home/user
Simhumileco
la source
1
cela manquerait des fichiers comme ..anythingou ...anythingetc. - stackoverflow.com/a/31438355/2351568 contient la regex correcte pour ce problème. || mais quand même utiliser shopt -s dotglobest toujours la meilleure solution!
DJCrashdummy
@DJCrashdummy malheureusement, je ne comprends pas pourquoi vous avez écrit votre attention. Après tout, ma solution prend en compte les cas sur lesquels vous écrivez. Regards
simhumileco
désolé faux texte! - le problème avec votre réponse est qu’il tiendra également compte de ( .et ..qui est équivalent au dossier courant et à son dossier). || mais toujours la réponse dans le lien l' explique plus loin et fournit une solution.
DJCrashdummy
2

Notez qu'il existe une astuce en ligne de commande (fonctionne dans, au moins, sh , bash et ksh ): il suffit de suffixer le répertoire from avec une barre oblique. Cela verser le contenu du du répertoire dans le au répertoire (ironiquement, j'avais d' abord appris cette astuce lorsque l' utilisation rsync ).

Exemple:

/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
Dustin Oprea
la source
2

Je suis venu ici avec Google pour trouver une solution au même problème, puis je me suis rendu compte que c'est facile à faire avec find. L'avantage est qu'il ne dépend pas du shell ou des utilitaires spéciaux qui peuvent ne pas être installés.

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

J'ai essayé le truc avec slash de fuite, mais cela n'a pas fonctionné pour moi.

Linus
la source
2

Ma solution à ce problème lorsque je dois copier tous les fichiers (y compris les .fichiers) dans un répertoire cible en conservant les autorisations est la suivante: (écraser si déjà existant)

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

yesest destiné à écraser automatiquement les fichiers de destination, rrécursif, vdétaillé, pconserver les autorisations.

Notez que le chemin source ne se termine pas par un/ (donc tous les fichiers / répertoire et fichiers. Sont copiés)

Le répertoire de destination se termine par la/ place du contenu du dossier source dans la destination.

Rajneesh Gadge
la source
1

J'ai vu que cp ne copie pas toujours les fichiers cachés et si vous souhaitez une commande qui semble fonctionner avec tous les dialectes linux / unix, vous devriez essayer d'utiliser:

cd /etc/skel
find | cpio -pdumv /home/user
Mikael Nyborg
la source
-2

À partir de K3b 2.0.3 au moins, une boîte de questions apparaît lorsque le répertoire est ajouté au projet, et vous demande si vous souhaitez inclure des fichiers cachés. Une autre question apparaît également, à savoir: liens. Jolies choses!

Fred James
la source
"une boîte de questions qui apparaît" - pour une commande shell (CLI)?
Scott