
En este artículo se revelarán algunas cosas no tan evidentes relacionadas con el uso de al copiar, el comportamiento ambiguo del comando cp al copiar, así como formas que permiten copiar correctamente una gran cantidad de archivos sin omisiones ni errores.
Supongamos que necesitamos copiar todo de la carpeta /source a la carpeta /target.
Lo primero que se nos ocurre es:
cp /source/* /targetInmediatamente corregimos este comando a:
cp -a /source/* /target Clave -a agregará la copia de todos los atributos, permisos y añadirá recursión. Cuando no se requiere una reproducción exacta de los permisos, basta con la opción -r.
Después de la copia, descubrimos que no se copiaron todos los archivos; se ignoraron archivos que comienzan con un punto, como:
.perfil
.local
.mc
y cosas similares.
¿Por qué ocurrió esto?
Porque los comodines son procesados por el shell (bash en un caso típico). Por defecto, bash ignora todos los archivos que comienzan con un punto, ya que los considera ocultos. Para evitar este comportamiento, debemos cambiarlo bash usando el comando:
shopt -s dotglob Para que este cambio de comportamiento se mantenga después de reiniciar, se puede crear un archivo wildcard.sh con este comando en la carpeta /etc/profile.d (quizás en su distribución la carpeta sea diferente).
Y si en el directorio fuente no hay archivos, el shell no podrá sustituir nada por el asterisco, y la copia también terminará con un error. Para prevenir esta situación, hay opciones failglob y nullglob. Necesitaremos configurar failglob, que no permitirá que el comando se ejecute. nullglob no servirá, ya que convierte una cadena con comodines sin coincidencias en una cadena vacía (de longitud cero), lo que causará un error para cp .
Sin embargo, si en la carpeta hay miles de archivos o más, vale la pena abandonar por completo el enfoque de usar comodines. La razón es que bash expande los comodines en una línea de comando muy larga como:
cp -a /souce/a /source/b /source/c …… /targetHay un límite en la longitud de la línea de comando, que podemos conocer usando el comando:
getconf ARG_MAXObtendremos la longitud máxima de la línea de comando en bytes:
2097152O:
xargs --show-limitsObtendremos algo como:
….
Longitud máxima del comando que podríamos usar: 2089314
….Así que, evitemos completamente el uso de comodines.
Simplemente escribamos
cp -a /source /target Y aquí nos encontramos con ambigüedades en el comportamiento cp. Si la carpeta /target no existe, obtendremos lo que necesitamos.
Sin embargo, si la carpeta target existe, los archivos se copiarán en la carpeta /target/source.
No siempre podemos eliminar la carpeta /target de antemano, ya que puede contener archivos que necesitamos y nuestro objetivo, supongamos, es complementar los archivos en /target con archivos de /source.
Si las carpetas de origen y destino tuviesen el mismo nombre, por ejemplo, si estuviéramos copiando de /source a /home/source, podríamos usar el comando:
cp -a /source /homeY después de la copia, los archivos en /home/source estarían complementados con los archivos de /source.
Aquí hay un acertijo lógico: podemos complementar los archivos en el directorio de destino, si las carpetas tienen el mismo nombre, pero si son diferentes, la carpeta de origen será colocada dentro del destino. ¿Cómo copiar archivos de /source a /target usando cp sin comodines?
Para sortear esta limitación perjudicial, utilizamos una solución no evidente:
cp -a /source/. /targetAquellos que están familiarizados con DOS y Linux ya lo han entendido todo: dentro de cada carpeta hay 2 carpetas invisibles «.» y «..», que son pseudo carpetas que linkean al directorio actual y al directorio superior.
- Al copiar
cpverifica la existencia y trata de crear /target. - Tal directorio existe y es /target
- Los archivos de /source se han copiado a /target correctamente.
Así que vamos a enmarcar con un borde grueso en nuestra mente o en la pared:
cp -a /source/. /target
El comportamiento de este comando es definitivo. Todo funcionará sin errores independientemente de si tienes un millón de archivos o ninguno.
Conclusiones
Si necesitas copiar cargas de trabajo dejarán de funcionar! archivos de una carpeta a otra, no uses comodines, en su lugar es mejor usar cp en combinación 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 la ausencia total de archivos.
Póscrito
propuso una variante similar del comando:
cp -a -T /source /target
cp -aT /source /target ATENCIÓN: el caso de la letra T importa. Si te confundes, obtendrás un completo desastre: la dirección de copia cambiará.
Agradecimientos:
- A la empresa por el apoyo y la oportunidad de publicar en su blog en Habr.
- Por la imagen . La imagen es muy grande y detallada, puedes abrirla en una ventana separada.
P.D. Envía errores reportados por mensaje privado. Aumentaré tu karma por esto.
Fuente: habr.com
