Estoy usando du
para monitorear continuamente la cantidad de datos escritos en unidades USB que estoy duplicando.
Comparo el uso del disco de las unidades de origen y de destino y muestro el progreso de la copia al usuario.
El problema es que du
informa el 100% de los datos presentes en la unidad de destino, aunque veo que todavía hay muchos datos en la memoria caché del sistema, el LED de la unidad parpadea y las unidades no están listas para ser extraídas.
Ejecuto rsync
y sync
en umount
secuencia para asegurarme de que los datos estén realmente allí antes de permitir que el usuario elimine la unidad de destino. Sin embargo , no puedo monitorear el sync
progreso. Por lo tanto, el usuario verá el 100% mucho antes de que las unidades estén realmente sincronizadas.
Me encantaría poder monitorear el progreso de la copia "real", ya que es lo que realmente importa: no sirve de nada ver rsync
la copia completa de un archivo de 1 GB en 25 segundos, mientras que tendré que esperar otros 5 minutos mientras sync
lo descargo. conducir (estoy exagerando, pero ya entiendes la idea).
Así es como superviso rsync
el progreso en un bucle para cada unidad:
PROGRESS="$(echo "$(du -s "/MEDIA/TARGET" 2>/dev/null | cut -f 1) / $(du -s "/MEDIA/SOURCE" 2>/dev/null | cut -f 1) " | bc -l)"
$PROGRESS
es un valor flotante entre 0 y 1, que indica la relación entre el uso de la unidad de origen y el uso de la unidad de destino.
¿Cómo puedo modificar esto para que considere solo los datos que ya están sincronizados con la unidad y no solo los que están esperando en la memoria caché del sistema?
Editar:
Descubrí que dd
puedo realizar escrituras omitiendo el caché del sistema. Hice una prueba y, de hecho, al copiar un archivo de esta manera se du
informan los valores reales y mis indicaciones de progreso finalmente serían precisas:
dd if=/media/SOURCE/file of=/media/TARGET/file bs=4M oflag=direct
Esto utiliza el caché de lectura, pero deshabilita el caché de escritura, lo que hace que el progreso sea más fácil de rastrear, sin realizar lecturas excesivas. El problema es que para usarlo dd
en lugar de rsync
necesito recrear manualmente la estructura del directorio. No necesito ocuparme de los atributos del archivo ni de las fechas de modificación.
Supongo que podría usar una combinación de y find
para recrear primero el árbol de directorios y luego copiar los archivos uno por uno. Me pregunto: ¿hay algún inconveniente en este enfoque?mkdir
dd
Respuesta1
Parece que la mejor manera de manejar esto es usarsalida directa de archivos. De esta forma du
las lecturas serán mucho más precisas.
Lamentablemente, solo dd
permite eso, por lo que debemos solucionar dos problemas:
dd
no sabe qué hacer con los directoriosdd
solo se puede copiar un archivo a la vez
Primero definamos los directorios de entrada y salida:
SOURCE="/media/source-dir"
TARGET="/media/target-dir"
Ahora entremos cd
en el directorio fuente para find
informar los directorios relativos que podemos manipular fácilmente:
cd "$SOURCE"
Duplicar el árbol de directorios de $SOURCE
a$TARGET
find . -type d -exec mkdir -p "$TARGET{}" \;
Duplicar archivos desde $SOURCE
omitiendo $TARGET
el caché de escritura (¡pero utilizando el caché de lectura!)
find . -type f -exec dd if={} of="$TARGET{}" bs=8M oflag=direct \;
Esto no preservará los tiempos de modificación de los archivos, la propiedad y otros atributos, pero para mí está bien.