¿Cómo copiar con cp para incluir archivos ocultos y directorios ocultos y sus contenidos?

392

¿Cómo puedo hacer una cp -rcopia absolutamente todos los archivos y directorios en un directorio

Requisitos:

  • Incluye archivos ocultos y directorios ocultos.
  • Sea un solo comando con una bandera para incluir lo anterior.
  • No es necesario confiar en la coincidencia de patrones en absoluto.

Mi feo, pero trabajando, hack es:

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

¿Cómo puedo hacer esto todo en un comando sin la coincidencia de patrones? ¿Qué bandera necesito usar?

once81
fuente
1
Más respuestas aquí, aunque no se ven tan bien; serverfault.com/questions/3154/…
Roel Van de Paar
Eleven81, considere cambiar la respuesta aceptada a la dada por @bruno pereira, porque evita crear una nueva carpeta. Si no, deje que este comentario sea una advertencia a los nuevos lectores para que también verifiquen la otra respuesta (la más votada). Tx.
Dr Beco

Respuestas:

265

No especifique los archivos:

cp -r /etc/skel /home/user

(Tenga en cuenta que /home/userno debe existir ya, o de lo contrario se creará /home/user/skel).

Randy Orrison
fuente
61
¿Es posible usar algo similar si /home/user/skel no existe?
bradley.ayers
@ bradley.ayers Creo que uno podría copiar en un subdirectorio temporal y luego moverlos al nivel superior (ya que moverse en el mismo disco es rápido). Menos que ideal, pero más corto que otras soluciones para mí.
Halil Özgür
77
@ bradley.ayers La respuesta de Bruno a continuación responde a su pregunta
Mark
1
Esta solución no me funcionó. No copió archivos ocultos. Estoy usando CentOS versión 6.5. La solución de @ Bruno hizo el truco.
Technext
2
En ubuntu / debian, esto coloca el directorio 'skel' dentro del directorio de destino y no los archivos repetidos dentro de skel. Use -T(sin objetivo) por debajo para un uso adecuado. ( -rTpara recursivo)
bshea
468

Digamos que creó la nueva carpeta (o que va a crear una) y desea copiar los archivos después de crear la carpeta.

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

Esto copiará todos los archivos / carpetas de forma recursiva /etc/skelen la carpeta ya existente creada en la primera línea.

Bruno Pereira
fuente
55
Si no me equivoqué, esto no copiaba archivos ocultos / punto.
Halil Özgür
34
Funciona bien para mi Tenga en cuenta que el '.' Es fundamental para que funcione.
Mark
12
Funciona, pero ¿por qué? No puedo encontrar una referencia a esto en el manual.
Julien Palard
55
Creo que funciona porque normalmente, esto crearía una nueva carpeta con el nombre de la última carpeta en el primer argumento. Sin embargo, dado que ese nombre es ., este comportamiento requeriría que creara un directorio ya existente, por lo que simplemente omite ese paso.
Zenexer
28
@Technext El globbing predeterminado en bash no incluye nombres de archivo que comiencen con a ., para cambiar que necesita usar el shopt -s dotglobcomando antes para poder incluir esos archivos. Entonces *, de manera predeterminada, solicita copiar todos los archivos de forma recursiva desde este directorio que se puede expandir utilizando *(que no incluye archivos ocultos de manera predeterminada). Mientras que en el otro extremo .está usando cp para copiar recursivamente todo de "este directorio".
Bruno Pereira
80

La forma correcta de hacerlo es usar la -T (--no-target-directory)opción y copiar recursivamente las carpetas (sin barras diagonales, asteriscos, etc.), es decir:

cp -rT /etc/skel /home/user

Esto copiará el contenido de /etc/skela /home/user(incluidos los archivos ocultos), creando la carpeta /home/usersi no existe; sin embargo, la -Topción evita que el contenido /etc/skelse copie en una nueva carpeta en /home/user/skelcaso de que la carpeta /home/userexista.

TechnocratiK
fuente
3
Respuesta correcta. +1
bshea
esta fue de hecho exactamente la respuesta correcta
Gaetan
Esta es la MEJOR respuesta del grupo; es el único que resuelve el problema sin complicarlo
ZaxLofful
funciona exactamente para copiar como se esperaba
Chetabahana
Me encanta cuando usas la bandera de cmd correcta para el caso.
Tran Triet
66

bashen sí tiene una buena solución, tiene un shell option, puedes cp, mvy así sucesivamente .:

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

y

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

La solución anterior es estándar de bash

NOTA:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set
Golfo pérsico
fuente
2
Eso es útil cuando desea copiar solo contenido sin crear un nuevo directorio dentro del destino. Especialmente cuando el directorio de destino es el punto de montaje.
kaszynek
3
Esta es realmente la mejor respuesta y llega al meollo de la pregunta ..
Stephen
77
Es setoptpara zsh, en caso de que alguien más se pregunte.
Pat
25

Use rsync:

rsync -rtv source_folder/ destination_folder/

usuario1084282
fuente
La mejor opción para mí, aunque uso --progress para tener más comentarios sobre todo el proceso.
Edenshaw
5

rsync es bueno, pero otra opción:

cp -a src/ dst/

De la ayuda principal:

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

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

   -R, -r, --recursive
          copy directories recursively
Wink Saville
fuente
Siempre usé cp -r. Gracias por mencionar cp -a
Pinaki Mukherjee
4

Si su directorio de origen y de destino tienen el mismo nombre, incluso si existe el directorio de destino, simplemente puede escribir:

cp -R /etc/skel /home/

Esto copiará el directorio / etc / skel en / home /, incluidos los archivos y directorios ocultos.

Finalmente, puede copiar el directorio y cambiarle el nombre en una sola línea:

cp -R /etc/skel /home/ && mv /home/skel /home/user
Gabriel Hautclocq
fuente
O simplemente puede usar cp -r /etc/skel /home/userpara cambiar el nombre skela user...
David
Así es, solo si / home / user todavía no existe.
Gabriel Hautclocq
4

Podrías usar rsync.

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

Incluso puedes copiar sobre ssh

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

Hay varios indicadores que puede usar: -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.

Página de manual de Rsync

RoshP
fuente
4

La forma más simple es:

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

La expresión {.,}*incluye todos los archivos y directorios (también comenzando con un punto).

Si no desea usar la expresión anterior, puede usar la cppropiedad, que es la capacidad de especificar múltiples fuentes para una carpeta de destino:

cp -r /etc/skel/* /etc/skel/.* /home/user
simhumileco
fuente
1
esto podría perder archivos como ..anythingo ...anythingetc. - stackoverflow.com/a/31438355/2351568 contiene la expresión regular correcta para este problema. || ¡Pero de todos modos usar shopt -s dotglobes la mejor solución!
DJCrashdummy
@DJCrashdummy desafortunadamente, no entiendo por qué escribiste tu atención. Después de todo, mi solución tiene en cuenta los casos sobre los que escribe. Saludos
simhumileco
perdon texto equivocado! - el problema con su respuesta es que también lo tendrá en cuenta .y ..(que es equivalente a la carpeta actual y que contiene). || pero aún así la respuesta en el enlace lo explica más y proporciona una solución.
DJCrashdummy
2

Tenga en cuenta que hay un truco en la línea de comandos (funciona en, al menos, sh , bash y ksh ): simplemente agregue el directorio from con una barra inclinada. Esto verter el contenido de la del directorio en el que el directorio (irónicamente, había aprendido primero sobre este truco cuando el uso de rsync ).

Ejemplo:

/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
fuente
2

Vine aquí buscando en Google una solución para el mismo problema, luego me di cuenta de que es fácil hacerlo con find. La ventaja es que no depende del shell o de las utilidades especiales que no se pueden instalar.

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

Intenté el truco con la barra diagonal final, pero eso no funcionó para mí.

Linus
fuente
2

Mi solución para este problema cuando tengo que copiar todos los archivos (incluidos los .archivos) a un directorio de destino que retiene los permisos es: (sobrescribir si ya existe)

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

yeses para sobrescribir automáticamente archivos de destino, rrecursivos, vdetallados, pretener permisos.

Tenga en cuenta que la ruta de origen no termina con a/ (por lo que se copian todos los archivos / directorios y archivos.)

El directorio de destino termina/ cuando colocamos el contenido de la carpeta de origen en el destino en su conjunto.

Rajneesh Gadge
fuente
1

He visto que cp no siempre copia archivos ocultos y si desea un comando que parece funcionar en todos los dialectos de Linux / Unix, debe intentar usar:

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

Al menos a partir de K3b 2.0.3, hay un cuadro de preguntas que aparece cuando se agrega el directorio al proyecto, que le pregunta si desea incluir archivos ocultos ... también hay una pregunta que surge para preguntar sobre incluir Enlaces. ¡Lindas cosas!

Fred James
fuente
"un cuadro de pregunta que aparece" - para un comando de shell (CLI)?
Scott