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.


Tal vez pueda interesarte


Compartí este artículo