tiempo de espera, romper tuberías y WC

20

Tuve la idea de comparar rápidamente algunos programas de descompresión. Por ejemplo, para gz, ejecutaría el comando:

timeout 10 zcat foo.gz | wc -c

Lo que mediría la cantidad de datos que el descompresor podría extraer en 10 segundos.

El único problema es que no funciona: como se elimina zcat, también se elimina wc, por lo que no obtengo el recuento de bytes, solo un Terminatedmensaje.

Entonces, la pregunta es: ¿hay alguna forma de obtener el recuento de wc , ya sea bloqueando la señal de alguna manera, o usando una alternativa en lugar de wc que imprima un resultado incluso cuando recibe una señal de término?


Por supuesto, hay alternativas:

  1. Escribir en un archivo temporal:
    timeout 10 zcat foo.gz > /dev/shm/x ; du -sb /dev/shm/x ; rm -r /dev/shm/x El problema con esto es que usa mucha memoria y también puede tener alguna penalización de rendimiento.

  2. Usando ulimit en su lugar:
    ulimit -t 10; zcat foo.gz | wc -c
    esto también funciona, pero mide solo el tiempo de CPU, por lo que no se mide la desaceleración debido a E / S (por ejemplo, porque la compresión es peor y se necesitan leer más bytes del disco).

  3. Hacer archivos de prueba más pequeños:
    Bueno, esto puede funcionar, por supuesto, y puede ser la mejor solución. Sin embargo, esto crea muchos archivos temporales.

P.Péter
fuente
66
Mientras leía "romper tuberías y wc", ¡pensé que al principio tenías problemas con tu plomería!
dr01

Respuestas:

21

Puede colocar el comando de tiempo de espera en una subshell y hacer que tenga éxito:

( timeout 10 <command> || true ) | wc -c
Marco
fuente
3
¿Hacer que un comando fallido tenga éxito? Oh, esto se ve tan malvado: D
Erathiel
17
@Erathiel ¿Quieres sonreír mientras eres malvado? Pruebe este (es equivalente al anterior):(timeout 10 <command> || :) | wc -c
Marco
1
Intenté usar una subshell, pero no pensé en hacer que tuviera éxito. ¡Excelente!
P.Péter
2

Justo después de publicar, pensé en usar tuberías con nombre para el proceso:

mkfifo /tmp/x; wc -c /tmp/x & timeout 10 zcat foo.gz > /tmp/x &

Esto parece funcionar.

P.Péter
fuente