Me doy cuenta de que esta pregunta es muy antigua, pero aquí hay una actualización que puede ser útil para otros que encuentren el camino aquí de la misma manera que yo.
Afortunadamente, la excelente respuesta de mvp ahora está obsoleta. Según las notas de la versión tar de GNU, SEEK_HOLE/SEEK_DATA se agregó en la versión 1.29, publicada el 16 de mayo de 2016. (Y dado que GNU tar v. 1.30 es estándar en Debian estable ahora, es seguro asumir que la versión tar ≥ 1.29 está disponible en casi todas partes).
Entonces, la forma de manejar archivos dispersos ahora es archivarlos con cualquier tar (GNU o BSD) que esté instalado en su sistema, y lo mismo para extraer.
Además, para los archivos dispersos que realmente contienen algunos datos, si vale la pena usar la compresión (es decir, los datos se pueden comprimir lo suficiente como para ahorrar una cantidad sustancial de espacio en disco, y el ahorro de espacio en disco vale la pena por el tiempo y los recursos de CPU necesarios para comprimirlos) :
tar -cSjf <archive>.tar.bz2 /path/to/sparse/file
aprovechará la funcionalidad SEEK_HOLE de tar para archivar de manera rápida y eficiente el archivo disperso y usará bzip2 para comprimir los datos reales.tar --use-compress-program=pbzip2 -cSf <archive>.tar.bz2 /path/to/sparse/file
, como se menciona en el comentario de marcin, hará lo mismo mientras también usando múltiples núcleos para la tarea de compresión.
En mi pequeño servidor doméstico con una CPU Atom de cuatro núcleos, usando pbzip2
contra bzip2
redujo el tiempo alrededor de un 25 o un 30%.
Con o sin compresión, esto le dará un archivo que no necesita ningún manejo especial de archivos dispersos, ocupa aproximadamente el tamaño 'real' del archivo disperso original (o menos si está comprimido) y se puede mover sin preocupaciones. sobre la inconsistencia entre las capacidades de archivos dispersos de las diferentes utilidades. Por ejemplo:cp
detectará automáticamente archivos dispersos y hará lo correcto, rsync
manejará archivos dispersos correctamente si usa el -S
bandera, y scp
no tiene opción para archivos dispersos (consumirá ancho de banda copiando ceros para todos los agujeros y la copia resultante será un archivo no disperso cuyo tamaño es el tamaño 'aparente' del original); pero todos ellos, por supuesto, manejarán un archivo tar sin problemas, ya sea que contenga archivos dispersos o no, sin ningún indicador especial.
Notas adicionales
- Al extraer,
tar
detectará automáticamente un archivo creado con-S
así que no hay necesidad de especificarlo. - Un archivo creado con
pbzip2
se almacena en fragmentos. Esto da como resultado que el archivo sea marginalmente más grande que sibzip2
se utiliza, pero también significa que la extracción puede ser multiproceso, a diferencia de un archivo creado conbzip2
. pbzip2
ybzip2
extraerá de manera confiable los archivos de los demás sin errores ni corrupción.
Respuesta corta: Utilice bsdtar
o GNU tar
(versión 1.29 o posterior) para crear archivos y GNU tar
(versión 1.26 o posterior) para extraerlos en otra caja.
Respuesta larga: Hay algunos requisitos para que esto funcione.
Primero, Linux debe tener al menos el kernel 3.1 (Ubuntu 12.04 o posterior sería suficiente), por lo que es compatible con SEEK_HOLE
funcionalidad.
Entonces, necesita la utilidad tar que pueda admitir esta llamada al sistema. GNU tar
lo admite desde la versión 1.29 (lanzada el 16/05/2016, debería estar presente de forma predeterminada desde Ubuntu 18.04), o bsdtar
desde la versión 3.0.4 (disponible desde Ubuntu 12.04) - instálelo usando sudo apt-get install bsdtar
.
Mientras bsdtar
(que usa libarchive
) es increíble, desafortunadamente, no es muy inteligente cuando se trata de descomprimir:estúpidamente requiere tener al menos tanto espacio libre en la unidad de destino como el tamaño del archivo sin descomprimir, sin tener en cuenta los agujeros. GNU tar
descomprimirá dichos archivos dispersos de manera eficiente y no verificará esta condición.
Este es un registro de Ubuntu 12.10 (Linux kernel 3.5):
$ dd if=/dev/zero of=1tb seek=1T bs=1 count=1
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.000143113 s, 7.0 kB/s
$ time bsdtar cvfz sparse.tar.gz 1tb
a 1tb
real 0m0.362s
user 0m0.336s
sys 0m0.020s
# Or, use gnu tar if version is later than 1.29:
$ time tar cSvfz sparse-gnutar.tar.gz 1tb
1tb
real 0m0.005s
user 0m0.006s
sys 0m0.000s
$ ls -l
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz
-rw-rw-r-- 1 autouser autouser 134 Nov 7 01:43 sparse-gnutar.tar.gz
$
Como dije anteriormente, desafortunadamente, descomprimir con bsdtar
no funcionará a menos que tenga 1 TB de espacio libre. Sin embargo, cualquier versión de GNU tar
funciona bien para descomprimir tal sparse.tar
:
$ rm 1tb
$ time tar -xvSf sparse.tar.gz
1tb
real 0m0.031s
user 0m0.016s
sys 0m0.016s
$ ls -l
total 8
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz