¿Cómo maneja "cp" los archivos abiertos?


15

Estoy teniendo dos directorios separados. El usuario carga un archivo en el primero. Hay un cronjob ejecutándose en segundo plano que copia los archivos cada 5 minutos en el segundo directorio.

¿Qué sucede si el usuario no ha completado su carga y el cronjob copia los archivos? Tenga en cuenta que los dos directorios son propiedad de diferentes usuarios, el cronjob se realiza como root.


lea esta publicación para ver qué sucede en ese caso: unix.stackexchange.com/questions/49299/…
Serge

Gracias, buena publicación que escribiste. Pero mi pregunta estaba más relacionada con cp, no con el manejo de archivos linux en general. Aunque quizás cp verifica si el archivo aún está abierto y espera hasta que se cierre o algo así.
Stuffy

No. cpno esperará hasta que el archivo esté completamente cargado. Como esperamos que la velocidad de transferencia de la red sea más baja que simplemente copiar el archivo de una ubicación a otra dentro del mismo host, en algún momento cpllegará al final del archivo actual y dejará de copiar. La solución a su problema puede ser simple: primero, el usuario carga el archivo con algún nombre de archivo especialmente maltratado (por ejemplo, antepuesto con .(carácter de punto). Cuando se realiza la transferencia, el usuario cambia el nombre al nombre original. Luego, el trabajo cron solo se ve para los archivos que no comienzan con ..
Serge

Respuestas:


17

cpNo sabe acerca de los archivos abiertos. Entonces, si el primer usuario carga un archivo grande y cronjob (o cualquier otro proceso) comienza a copiar este archivo, solo copiará tanto como ya se escribió. Puede pensar en esto de esta manera: cphace una copia de lo que está actualmente en el disco, sin importar si el archivo está completo. De lo contrario, no podría copiar archivos de registro, por ejemplo.


Gracias, eso es lo que quería saber! ¿Hay una manera simple de evitar eso? Revisé la página de manual de cp pero no encontré nada útil.
Stuffy

¿Para hacer qué exactamente? ¿Copiar todos los archivos excepto los abiertos? No creo que haya una manera fácil de hacer esto (aparte de escribir su propio script que use fuser+ cp. Tal copia realmente sería muy poco confiable. No copiará ningún archivo que se abra en el editor de texto, por ejemplo.
Krzysztof Adamski

@Stuffy, ¿tal vez en tu cronjob podrías enumerar archivos abiertos lsof? El resultado de eso está destinado a ser fácil de procesar. Puede filtrar los archivos que se están abriendo (digamos, por una instancia de cp) para escribir.
Wojtek Rzepala

@WojtekRzepala, echaré un vistazo a esto, gracias. Tal vez escribiré un pequeño guión que será ejecutado por el cronjob
Stuffy

@Stuffy: Tenga en cuenta que puede no ser realmente confiable si no es ejecutado por el usuario root (el mismo problema es, por fusersupuesto), ya que esta herramienta puede no mostrar todos los archivos.
Krzysztof Adamski

7

cpno sabe qué otros programas pueden tener abiertos los archivos. No hay magia en cp. El diseño de Unix evita a propósito poner cualquier tipo de bloqueos en los archivos a menos que haya una razón convincente (lo que significa que el núcleo lo necesita). Sobre este tema, vea ¿La redirección de salida a un archivo aplica un bloqueo en el archivo?

Tales situaciones, donde un archivo es producido por un productor y, una vez completado, consumido por un consumidor, son comunes. La forma habitual de manejar esto es hacer que el productor escriba un archivo temporal que el consumidor no buscará, luego, una vez que el productor haya terminado, mueva el archivo a un lugar donde el consumidor lo encuentre. Mover un archivo (en el mismo sistema de archivos) es una operación atómica: en algún momento, para el consumidor, el archivo cambia de no estar allí a estar allí.

Por lo tanto, organice su trabajo de carga para mover los archivos a un directorio diferente cuando haya terminado de cargar. Apunte el trabajo cron a este directorio diferente.


6

Parece que quieres hacer un trabajo de sincronización de directorios.

Porque la opción -u, --update decp

copiar solo cuando el archivo SOURCE es más nuevo que el archivo de destino o cuando falta el archivo de destino

Entonces puede agregar un cronjob como el cp -auv SOURCEDIR/* DESTDIRque copiará aquellos archivos cuya hora de modificación ha cambiado. Eso significa DESTDIRque eventualmente obtendrá la copia completa mientras finaliza la carga.

rsyncpuede hacer el mismo trabajo por ejemplo, rsync -av SOURCEDIR/ DESTDIR.

Aunque se aplica la opción -a, algunos atributos específicos (p. Ej., Propiedad) solo pueden ser preservados por el superusuario.

Ver man cp, man rsyncpara más detalles.


Solo tenga cuidado de no depender de las entradas recientes en la carpeta de destino; es posible que no sean archivos completos.
dubiousjim
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.