¿Por qué parece que el tar omite el contenido del archivo cuando el archivo de salida es / dev / null?


21

Tengo un directorio con más de 400 GiB de datos. Quería comprobar que todos los archivos se pueden leer sin errores, por lo que una forma sencilla que pensé fue que taren /dev/null. Pero en cambio veo el siguiente comportamiento:

$ time tar cf /dev/null .

real    0m4.387s
user    0m3.462s
sys     0m0.185s
$ time tar cf - . > /dev/null

real    0m3.130s
user    0m3.091s
sys     0m0.035s
$ time tar cf - . | cat > /dev/null
^C

real    10m32.985s
user    0m1.942s
sys     0m33.764s

El tercer comando anterior fue detenido a la fuerza por Ctrl+ Cdespués de haberlo ejecutado durante bastante tiempo. Además, mientras los dos primeros comandos estaban funcionando, el indicador de actividad del dispositivo de almacenamiento que contenía .casi siempre estaba inactivo. Con el tercer comando, el indicador se ilumina constantemente, lo que significa ocupado extremo.

Por lo tanto, parece que, cuando tarpuede descubrir que su archivo de salida es /dev/null, es decir, cuando /dev/nullse abre directamente para tener el identificador de archivo en el que tarescribe, el cuerpo del archivo parece omitido. (Agregar vopción a tarimprime todos los archivos en el directorio siendo tar'rojo').

Entonces me pregunto, ¿por qué es así? ¿Es algún tipo de optimización? En caso afirmativo, ¿por qué tarquerría hacer una optimización tan dudosa para un caso tan especial?

Estoy usando GNU tar 1.26 con glibc 2.27 en Linux 4.14.105 amd64.


77
Como alternativa práctica, considere algo así find . -type f -exec shasum -a256 -b '{}' +. No sólo hecho de leer y suma de comprobación de todos los datos, pero si almacena la salida, se puede volver a ejecutarlo más tarde para comprobar que el contenido de los archivos no ha cambiado.
Ilmari Karonen

Para medir las cosas también se puede utilizar pv: tar -cf - | pv >/dev/null. Eso evita el problema y le brinda información sobre el progreso (las diversas pvopciones)
xenoid

Llegaste a una característica de fallo bien conocida de GNU tar. Úselo gtar -cf /dev/zero ...para obtener lo que le gusta.
schily

Respuestas:


25

Que es una optimización documentado :

Cuando se crea el archivo /dev/null, GNU tar intenta minimizar las operaciones de entrada y salida. El sistema de copia de seguridad de Amanda, cuando se usa con GNU tar, tiene un pase de dimensionamiento inicial que utiliza esta función.


44
Ah, esto no se describió en la página del manual que había instalado. Debería haber intentado en su info tarlugar ...
Ruslan

99
Realmente deberían mantener sincronizadas las páginas de manual y de información, es prácticamente un error que no lo sean
Xen2050

99
@Ruslan Con la mayoría de las utilidades de GNU, la página de manual solo contiene un breve resumen, básicamente solo lo suficientemente bueno cuando recuerda que tiene una opción para hacer algo pero no recuerda el nombre de la opción. La documentación completa está en un formato que no se traduce bien a las páginas de manual y está disponible con infoo como HTML en un navegador.
Gilles 'SO- deja de ser malvado'


8

Esto puede suceder con una variedad de programas, por ejemplo, tuve ese comportamiento una vez cuando estaba usando cp file /dev/null; en lugar de obtener una estimación de la velocidad de lectura de mi disco, el comando regresó después de unos pocos milisegundos.

Hasta donde recuerdo, eso fue en Solaris o AIX, pero el principio se aplica a todo tipo de sistemas unix-y.

En los viejos tiempos, cuando un programa copiaba un archivo en algún lugar, alternaba entre readllamadas que obtenían algunos datos del disco (o lo que sea que se refiere el descriptor de archivo) a la memoria (con una garantía de que todo está allí cuando readregresa) y writellamadas (que toma la mayor parte de la memoria y envía el contenido al destino)

Sin embargo, hay al menos dos nuevas formas de lograr lo mismo:

  • Linux tiene llamadas al sistema copy_file_range(no es portátil a otros unixes) y sendfile(algo portátil; originalmente estaba destinado a enviar un archivo a la red, pero ahora puede usar cualquier destino). Están destinados a optimizar las transferencias; si el programa usa uno de esos, es fácilmente concebible que el núcleo reconozca el objetivo /dev/nully convierta la llamada del sistema en un no-op

  • Los programas pueden usar mmappara obtener el contenido del archivo en lugar de read, esto básicamente significa "asegurarme de que los datos estén allí cuando intento acceder a esa porción de memoria" en lugar de "asegurarme de que los datos estén allí cuando vuelva la llamada del sistema". Entonces, un programa puede mmapenviar el archivo fuente y luego invocar writeese trozo de memoria asignada. Sin embargo, como la escritura /dev/nullno necesita acceder a los datos escritos, la condición "asegúrese de que esté allí" nunca se activa, lo que hace que el archivo tampoco se lea.

No estoy seguro de si gnu tar usa alguno y cuál de estos dos mecanismos cuando detecta que está escribiendo /dev/null, pero son la razón por la cual cualquier programa, cuando se usa para verificar las velocidades de lectura , debe ejecutarse en | cat > /dev/nulllugar de > /dev/null, y por qué | cat > /dev/nulldebería ser evitado en todos los demás casos.


Creo que la implicación en la tarpágina de información de GNU (ver otra respuesta) es que tiene un modo especial para esto, que presumiblemente solo envía archivos de estadísticas sin abrirlos. De hecho, solo verifiqué tar cf /dev/null foo*un par de archivos y sí, solo newfstatat(..., AT_SYMLINK_NOFOLLOW)llamadas al sistema, ni siquiera una open()que pueda actualizar el atime. Pero +1 para describir los mecanismos donde esto puede suceder sin tener que detectarlo especialmente.
Peter Cordes

¿Debe la explicación de mmap leer "acceder a los datos leídos " en lugar de "acceder a los datos escritos "?
Wayne Conrad

Ver también splice(2)en Linux. En realidad, reemplazar cat > /dev/nullcon pv -q > /dev/null(que se usa splice()en Linux) probablemente reduciría la sobrecarga. O dd bs=65536 skip=9999999999 2> /dev/null, o wc -c > /dev/nullo tail -c1 > /dev/null...
Stéphane Chazelas
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.