Comando cp: copiar correctamente carpetas de archivos en *nix

Comando cp: copiar correctamente carpetas de archivos en *nix

Este artículo revelará algunas cosas no obvias relacionadas con el uso de comodines al copiar, comportamiento de comando ambiguo cp al copiar, así como métodos que le permiten copiar correctamente una gran cantidad de archivos sin saltarlos ni bloquearlos.

Digamos que necesitamos copiar todo desde la carpeta/fuente a la carpeta/destino.

Lo primero que me viene a la mente es:

cp /source/* /target

Corrijamos inmediatamente este comando para:

cp -a /source/* /target

Llave -a agregará la copia de todos los atributos, derechos y agregará recursividad. Cuando no se requiere la reproducción exacta de los derechos, una clave es suficiente -r.

Después de copiar, encontraremos que no se copiaron todos los archivos: archivos que comienzan con un punto como:

.profile
.local
.mc

y similares.

¿Por qué sucedió esto?

Debido a que los comodines son procesados ​​por el shell (bash en un caso típico). De forma predeterminada, bash ignorará todos los archivos que comiencen con puntos, ya que los trata como ocultos. Para evitar este comportamiento tendremos que cambiar el comportamiento. bash usando el comando:

shopt -s dotglob

Para garantizar que este cambio de comportamiento persista después de reiniciar, puede crear un archivo comodín.sh con este comando en la carpeta /etc/profile.d (Quizás tu distribución tenga una carpeta diferente).

Y si no hay archivos en el directorio de origen, entonces el shell no podrá sustituir nada en lugar del asterisco y la copia también fallará con un error. Hay opciones frente a esta situación failglob и nullglob. Necesitaremos establecer failglob, lo que impedirá que se ejecute el comando. nullglob no funcionará, ya que convierte una cadena con comodines que no encontró una coincidencia en una cadena vacía (longitud cero), que por cp provocará un error.

Sin embargo, si hay miles de archivos o más en la carpeta, entonces se debe abandonar por completo el método de los comodines. El hecho es que bash expande los comodines en una línea de comando muy larga como:

cp -a /souce/a /source/b /source/c …… /target

Hay un límite en la longitud de la línea de comando, que podemos averiguar usando el comando:

getconf ARG_MAX

Obtengamos la longitud máxima de la línea de comando en bytes:

2097152

Или:

xargs --show-limits

Obtenemos algo como:

….
Maximum length of command we could actually use: 2089314
….

Entonces, prescindamos por completo de los comodines.

solo escribamos

cp -a /source /target

Y aquí nos enfrentamos a una ambigüedad de comportamiento. cp. Si la carpeta /target no existe, obtendremos lo que necesitamos.

Sin embargo, si la carpeta de destino existe, los archivos se copiarán a la carpeta /destino/fuente.

No siempre podemos eliminar la carpeta /target por adelantado, ya que puede contener archivos que necesitamos y nuestro objetivo, por ejemplo, es complementar los archivos en /target con archivos de /source.

Si las carpetas de origen y de destino tuvieran el mismo nombre, por ejemplo, estuviéramos copiando de /fuente a /home/fuente, entonces podríamos usar el comando:

cp -a /source /home

Y después de copiar, los archivos en /home/source se complementarían con archivos de /source.

Este es un problema lógico: podemos agregar archivos en el directorio de destino si las carpetas tienen el mismo nombre, pero si son diferentes, entonces la carpeta de origen se colocará dentro del destino. ¿Cómo copiar archivos de/fuente a/destino usando cp sin comodines?

Para sortear esta dañina limitación, utilizamos una solución no obvia:

cp -a /source/. /target

Quienes estén familiarizados con DOS y Linux ya lo han entendido todo: dentro de cada carpeta hay 2 carpetas invisibles “.” y “..”, que son enlaces de pseudocarpetas a los directorios actuales y superiores.

  • Al copiar cp comprueba la existencia e intenta crear /target/.
  • Dicho directorio existe y es /target
  • Los archivos de /source se copian a /target correctamente.

Así que cuélgalo en un marco llamativo en tu memoria o en la pared:

cp -a /source/. /target

El comportamiento de este comando es claro. Todo funcionará sin errores, sin importar si tienes un millón de archivos o ninguno.

Hallazgos

Si necesitas copiar todos archivos de una carpeta a otra, no usamos comodines, es mejor usarlos en su lugar cp combinado con un punto al final de la carpeta de origen. Esto copiará todos los archivos, incluidos los ocultos, y no fallará con millones de archivos o ningún archivo.

Epílogo

vmspike sugirió una versión de comando con un resultado similar:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

NOTA: letra mayúscula T tiene el significado. Si lo mezcla, obtendrá una completa basura: la dirección de copia cambiará.
Etiquetas:

  • Las empresas RUVDS.COM por apoyo y la oportunidad de publicar en su blog sobre Habré.
  • Por imagen Concepto triple. La imagen es muy grande y detallada, se puede abrir en una ventana separada.

PS Envíe cualquier error que observe en un mensaje privado. Aumento mi karma por esto.

Comando cp: copiar correctamente carpetas de archivos en *nix

Fuente: habr.com

Añadir un comentario