Script Bash - Retrasar el comando cp hasta que se complete la escritura del archivo

cp /Folder1/*.mov /Folder2/
cp /Folder1/*.mov /Folder3
rm /Folder1/*.mov

Esto se ejecuta cada 60 segundos usando Chron que copia cualquier archivo *.mov de una carpeta a otras 2 carpetas y luego elimina el archivo.

Si el archivo tarda más de 60 segundos en escribirse, el script se ejecuta y copia todo lo que hay en la carpeta y lo corrompe. (O si el script simplemente se ejecuta cuando se está escribiendo un archivo).

¿Cómo puedo hacer una declaración condicional para hacer que el script espere hasta que se complete la escritura del archivo?

¿Quizás usar acciones de carpeta en su lugar? Por ejemplo: simplehelp.net/2007/01/30/… Puede crearlos usando Automator.app
¿Está copiando los archivos en el mismo sistema de archivos?
Usaría rsync en lugar de cp (o incluso solo mv)
Esto es parte de un sistema que usamos para permitir que los clientes externos vean renderizaciones preliminares de proyectos. La idea es que coloquemos un archivo *.mov en esta carpeta y lo copie en otra carpeta que Adobe Media Encoder observe y luego codifique automáticamente un archivo más pequeño y luego copie ese archivo en una carpeta de Dropbox para que los clientes lo vean.
Mismo sistema de archivos, he intentado usar Automator pero sin mucha suerte...
La mejor opción que he visto hasta ahora es usar LSOF. Pero mi código-foo es débil y no sé cómo poner estos comandos en un ciclo condicional usando LSOF.
Una última pregunta: ¿el sistema de archivos es HFS+?
Esto está en un sistema de canal de fibra XSAN. No estoy seguro de si eso responde adecuadamente a la pregunta... No creo que XSAN use HFS. Mi conocimiento es limitado.
¿Por qué no usar mv? Los datos se copian solo con el puntero al archivo, por lo que se ejecutarán en menos de 60 segundos.
Propondría el siguiente algoritmo teniendo una mejor comprensión de su requerimiento. Tome una instantánea de los archivos .mov disponibles en la Carpeta 1 y muévalos a una carpeta temporal (sugerencia: use buscar). Luego, los archivos se copian a sus respectivas carpetas desde la carpeta temporal y la carpeta temporal y sus archivos se desvinculan. Esto debería detener cualquier colisión si cron (tenga en cuenta la ortografía) inicia otra instancia de su secuencia de comandos cron.
Gracias fd0, eso suena bien y probablemente resolvería mi problema. Supongo que mi problema es que realmente no sé cómo implementar eso... ¿La idea que tenía era usar lsof para crear un ciclo condicional como este? Si algún proceso está usando algún archivo en la carpeta X, haga eco "Esperando 10 segundos..." espere 10 segundos, de lo contrario haga cp cp rm

Respuestas (1)

Bloquear archivo

Considere crear un bloqueo para anotar la copia en curso, vea bloquear su secuencia de comandos (contra la ejecución en paralelo) :

#!/bin/sh

# Path to a lock folder
LOCK_PATH="/tmp/copying.lock"

# Ensure the lock is removed should the copy fail
trap 'rmdir "/tmp/copying.lock"; exit' 1 6 15

if mkdir "$LOCK_PATH"; then
    # Lock file did not exist and was created

    # Perform commands
    cp /Folder1/*.mov /Folder2/
    cp /Folder1/*.mov /Folder3
    rm /Folder1/*.mov   

    # Remove the lock
    rmdir "$LOCK_PATH"
fi

La secuencia de comandos anterior solo se copia si no existe una carpeta en /tmp/copying.lock.

Copiar y mover

En lugar de copiar directamente en la ubicación final, considere realizar la copia en una ubicación temporal. Luego mueva los archivos. Un movimiento es rápido, tiende a ser atómico y es menos probable que dañe los archivos.

Alternativamente, puede copiar usando una herramienta como rsyncla que incluye banderas para ayudar a protegerse contra estos problemas.

A su secuencia de comandos le falta una trampa o la secuencia de comandos podría bloquearse si se cierra de manera anormal. Algo comotrap 'rmdir /tmp/copy.lock; exit' 1 6 15
Gracias @fd0. Por favor, siéntase libre de editar y agregar en la línea.
Le daré una oportunidad e informaré en un momento. ¡Gracias Graham, fd0 y otros que han ayudado! ¡Aquí va!
Hola chicos, probé esto, pero podría estar haciendo algo mal. No funcionará de la forma en que lo tengo a menos que cree manualmente la carpeta /tmp/ en el directorio.
Además, tampoco elimina la carpeta /copying.lock, ¿quizás estoy señalando la variable incorrectamente?
Ah, ok, actualicé la línea de trampa para atrapar 'rmdir "$ LOCK_PATH"; exit' 1 6 15 y eso lo arregló parcialmente, pero por alguna razón el rm -f "$LOCK_PATH" no funciona...
Por ahora, intente eliminar la traplínea por completo. Está allí sólo en caso de problemas. El final rm -fes responsable de eliminar la carpeta, después de la copia exitosa.
Para ayudar con la depuración, cree un archivo de texto que contenga su secuencia de comandos completa y agregue el sufijo .command. A continuación, haga doble clic en el archivo de texto para verlo iniciar en Terminal.app. Debería poder ver mejor los problemas. Cuando eso funcione, puede integrarlo en Chron. Alternativamente, puedo resolver esto con un evento de Power Manager , que escribí.
El archivo de bloqueo no existía y fue creado, Copiando... cp: /Volumes/PROOFS_WATCH/*.mov: No existe tal archivo o directorio cp: /Volumes/PROOFS_WATCH/*.mov: No existe tal archivo o directorio rm: /Volumes/ PROOFS_WATCH/*.mov: No existe tal archivo o directorio rm: /Volumes/PROOFS_WATCH/copy.lock: es un directorio cerrar sesión [Proceso completado]
#!/bin/bash # Ruta a una carpeta de bloqueo LOCK_PATH="/Volumes/PROOFS_WATCH/copy.lock" # trap 'rmdir "$LOCK_PATH"; exit' 1 6 15 if mkdir "$LOCK_PATH"; luego echo "El archivo de bloqueo no existía y fue creado, copiando..." # Ejecutar comandos /Volumes/PROOFS_WATCH/*.mov # Eliminar el bloqueo rm -f "$LOCK_PATH" fi
Por favor, puede comenzar una nueva pregunta. Eso ayudará con el formato y atraerá más atención.
Claro, no hay problema, bastante nuevo en secuencias de comandos e intercambio de pilas...