Este artículo demuestra como copiar archivos y directorios en Linux utilizando la herramienta cp, incluyendo algunos usos especiales de la misma.
Copiar un archivo
Copiar un archivo en Linux es tan simple como ejecutar:
$ cp fuente destino
Por ejemplo, crear una copia del archivo ~/Downloads/IMG_2545.JPG
con el nombre imagen.jpg
en la ruta /tmp/imagen.png
(es decir, en el directorio /tmp
:
emi@hal9000:~$ ll ~/Downloads/IMG_2545.JPG -rw-r--r-- 1 emi emi 2584036 Aug 3 2018 /home/emi/Downloads/IMG_2545.JPG emi@hal9000:~$ cp ~/Downloads/IMG_2545.JPG /tmp/imagen.jpg emi@hal9000:~$ ll /tmp/imagen.jpg -rw-r--r-- 1 emi emi 2584036 Oct 17 10:15 /tmp/imagen.jpg
Es posible copiar un archivo directamente dentro de un directorio, pasándolo como parámetro destino. Por ejemplo:
emi@hal9000:~$ cp ~/Downloads/IMG_2545.JPG /tmp/ emi@hal9000:~$ ll /tmp/IMG_2545.JPG -rw-r--r-- 1 emi emi 2584036 Oct 17 10:18 /tmp/IMG_2545.JPG
Copiar directorios
Si se desea copiar un directorio recursivamente (incluyendo todos sus subdirectorios y archivos) es necesario emplear la opción -r
:
$ cp -r fuente destino
Veamos un ejemplo copiando el directorio /etc
completo:
emi@hal9000:~$ ll /etc/ | head total 1112 -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime drwxr-xr-x 2 root root 12288 Aug 21 10:29 alternatives -rw-r--r-- 1 root root 401 May 29 2017 anacrontab drwxr-xr-x 3 root root 4096 May 2 18:20 apache2 drwxr-xr-x 3 root root 4096 May 2 18:17 apm drwxr-xr-x 3 root root 4096 May 3 16:36 apparmor drwxr-xr-x 5 root root 4096 Sep 9 07:42 apparmor.d drwxr-xr-x 6 root root 4096 Aug 21 10:53 apt emi@hal9000:~$ cp -r /etc/ /tmp/etc-copia 2>/dev/null emi@hal9000:~$ ll /tmp/etc-copia/ | head total 1080 -rw-r--r-- 1 emi emi 2981 Oct 17 09:06 adduser.conf -rw-r--r-- 1 emi emi 44 Oct 17 09:06 adjtime drwxr-xr-x 2 emi emi 4096 Oct 17 09:06 alternatives -rw-r--r-- 1 emi emi 401 Oct 17 09:06 anacrontab drwxr-xr-x 3 emi emi 4096 Oct 17 09:06 apache2 drwxr-xr-x 3 emi emi 4096 Oct 17 09:06 apm drwxr-xr-x 3 emi emi 4096 Oct 17 09:06 apparmor drwxr-xr-x 5 emi emi 4096 Oct 17 09:06 apparmor.d drwxr-xr-x 6 emi emi 4096 Oct 17 09:06 apt
Notar que, al copiar recursivamente, no se preserva el ownership (usuario y grupo dueños de cada archivo) ni la fecha de modificación. Los archivos copiados están a nombre de "emi" en lugar de "root" y la fecha de modificación es la fecha actual.
Si se desean preservar todos los atributos, y que los archivos sean copias exactas tanto de los datos como de sus metadatos, es necesario pasar a la siguiente opción.
Copiar recursivamente preservando permisos y ownership
Para mantener todos los metadatos, incluyendo permisos, usuario, grupo y fechas (de modificación y acceso si el sistema de archivos lo soporta) es necesario recurrir a la opción -a
:
# cp -a fuente destino
Cabe destacar que, a fin de preservar usuario/grupo, es necesario copiar como superusuario (los usuarios no privilegiados no tienen la capacidad de cambiar el ownsership):
root@hal9000:~# rm -fr /tmp/etc-copia root@hal9000:~# cp -a /etc/ /tmp/etc-copia 2>/dev/null root@hal9000:~# ll /tmp/etc-copia/ | head total 1104 -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime drwxr-xr-x 2 root root 4096 Aug 21 10:29 alternatives -rw-r--r-- 1 root root 401 May 29 2017 anacrontab drwxr-xr-x 3 root root 4096 May 2 18:20 apache2 drwxr-xr-x 3 root root 4096 May 2 18:17 apm drwxr-xr-x 3 root root 4096 May 3 16:36 apparmor drwxr-xr-x 5 root root 4096 Sep 9 07:42 apparmor.d drwxr-xr-x 6 root root 4096 Aug 21 10:53 apt
Ahora se observa que las fechas de modificación de los archivos coinciden con las del origen. Esta es la forma correcta de duplicar archivos como copias exactas.
Copiar archivos sobre un directorio existente
Hay diferentes opciones para copiar archivos sobre un destino ya existente y que contiene archivos. El problema es ¿qué se hace con los archivos que ya existen en el destino y tienen el mismo nombre que archivos en el origen? Por defecto, cp
sobrescribe archivos en el destino sin consultar:
# cp -r /etc/ /tmp/etc-copia # cp -a /etc/ /tmp/etc-copia
Lo más común es pedir la intervención del usuario para saber si se desea sobrescribir el archivo en el destino o no. Para ello se debe agregar la opción -i
:
# cp -ri /etc/ /tmp/etc-copia # cp -ai /etc/ /tmp/etc-copia
Por ejemplo:
root@hal9000:~# cp -ai /etc/ /tmp/etc-copia/ cp: overwrite '/tmp/etc-copia/etc/console-setup/compose.ARMSCII-8.inc'? y cp: overwrite '/tmp/etc-copia/etc/console-setup/compose.CP1251.inc'? y cp: overwrite '/tmp/etc-copia/etc/console-setup/compose.CP1255.inc'? n cp: overwrite '/tmp/etc-copia/etc/console-setup/compose.CP1256.inc'?
Solo basta responder "y" para sobrescribir u "o" para omitir. Por supuesto es posible utilizar la combinación de teclas Ctrl+C
para terminar el proceso y abortar la copia.
Otra opción consiste en crear un backup automático de cada archivo que se sobrescribe en el destino. Para ello, emplear la opción --backup
:
# cp -ab fuente destino # cp -a -b fuente destino # cp -a --backup=simple fuente destino
Veamos un ejemplo:
root@hal9000:~# rm -fr /tmp/etc-copia root@hal9000:~# cp -a /etc /tmp/etc-copia root@hal9000:~# ll /tmp/etc-copia/ | head total 1104 -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime drwxr-xr-x 2 root root 4096 Aug 21 10:29 alternatives -rw-r--r-- 1 root root 401 May 29 2017 anacrontab drwxr-xr-x 3 root root 4096 May 2 18:20 apache2 drwxr-xr-x 3 root root 4096 May 2 18:17 apm drwxr-xr-x 3 root root 4096 May 3 16:36 apparmor drwxr-xr-x 5 root root 4096 Sep 9 07:42 apparmor.d drwxr-xr-x 6 root root 4096 Aug 21 10:53 apt root@hal9000:~# cp -ab /etc/* /tmp/etc-copia root@hal9000:~# ll /tmp/etc-copia | head total 1728 -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf~ -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime~ drwxr-xr-x 2 root root 20480 Aug 21 10:29 alternatives -rw-r--r-- 1 root root 401 May 29 2017 anacrontab -rw-r--r-- 1 root root 401 May 29 2017 anacrontab~ drwxr-xr-x 3 root root 4096 May 2 18:20 apache2 drwxr-xr-x 3 root root 4096 May 2 18:17 apm
El método de backup simple (-b
equivale a --backup=simple
) mantiene una única copia con un caracter ~
al final del nombre.
Hay diferentes métodos de control de versiones disponibles. Los valores que puede tomar como parámetro la opción --backup
son "numbered", "existing" o "simple". El valor "numbered" crea copias numeradas empleando un valor numérico acumulativo luego del caracter ~
:
root@hal9000:~# cp -a --backup=numbered /etc/* /tmp/etc-copia root@hal9000:~# cp -a --backup=numbered /etc/* /tmp/etc-copia root@hal9000:~# ll /tmp/etc-copia | head total 2988 -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf~ -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf.~1~ -rw-r--r-- 1 root root 2981 May 2 18:05 adduser.conf.~2~ -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime~ -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime.~1~ -rw-r--r-- 1 root root 44 Oct 16 14:22 adjtime.~2~ drwxr-xr-x 2 root root 36864 Aug 21 10:29 alternatives
Notar el uso del comodín (*
) para que cp
ingrese dentro del directorio. De lo contrario lo omite, aunque se use la opción -a
o -r
.
Por otro lado, el mecanismo de control de versiones puede ser controlado mediante la variable de entorno VERSION_CONTROL
. Para más información, consultar la página de manual de cp
(man cp
).
Por último y respecto a la herramienta cp
, existen extensiones de GNU al estándar POSIX como -n
(o --no-clobber
) y -u
(o --update
) que permiten no sobrescribir archivos y sólo sobrescribir cuando el origen es más nuevo, respectivamente. Sin embargo, estas opciones tienen problemas cuando se utilizan recursivamente (en conjunto con -r
o -a
), y (al no ser parte del estándar POSIX) pueden no funcionar en otras plataformas Unix no-GNU.
Mover archivos
Finalmente, en GNU/Linux (como en todo sistema operativo de la familia Unix) mover un archivo consiste en renombrarlo. Para ello se utiliza la herramienta mv
, la cual toma aproximadamente los mismos parámetros que cp
:
$ mv fuente destino
Ejemplo:
root@hal9000:~# mv /tmp/etc-copia /tmp/etc-BACKUP root@hal9000:~# ll -d /tmp/etc* drwxr-xr-x 127 root root 20480 Oct 17 10:06 /tmp/etc-BACKUP
Para más información: man mv
.