Auszeit, Rohrbruch und WC


20

Ich hatte die Idee, einige Dekomprimierungsprogramme schnell zu vergleichen. ZB für gz würde ich den Befehl ausführen:

timeout 10 zcat foo.gz | wc -c

Dies würde die Datenmenge messen, die der Dekomprimierer in 10 Sekunden extrahieren könnte.

Das einzige Problem ist, dass es nicht funktioniert: Wenn zcat getötet wird, wird auch wc getötet, sodass ich nicht die Byteanzahl erhalte, sondern nur eine TerminatedNachricht.

Die Frage ist also: Gibt es eine Möglichkeit, die Zählung von wc zu erhalten , indem entweder das Signal auf irgendeine Weise blockiert wird oder statt wc eine Alternative verwendet wird, die ein Ergebnis ausgibt, selbst wenn es ein Termsignal erhält.


Natürlich gibt es Alternativen:

  1. In eine temporäre Datei schreiben:
    timeout 10 zcat foo.gz > /dev/shm/x ; du -sb /dev/shm/x ; rm -r /dev/shm/x Das Problem dabei ist, dass viel Speicher benötigt wird und auch Leistungseinbußen auftreten können.

  2. Stattdessen ulimit verwenden:
    ulimit -t 10; zcat foo.gz | wc -c
    Dies funktioniert auch, misst aber nur die CPU-Zeit, sodass eine Verlangsamung aufgrund von E / A (z. B. weil die Komprimierung schlechter ist und mehr Bytes von der Festplatte gelesen werden müssen) nicht gemessen wird.

  3. Kleinere Testdateien erstellen:
    Das kann natürlich funktionieren und ist möglicherweise die schönste Lösung. Dadurch werden jedoch viele temporäre Dateien erstellt.


6
Als ich "Rohre brechen und wc" las, dachte ich zuerst, Sie hätten Probleme mit Ihrer Installation!
dr01

Antworten:


21

Sie können den Befehl timeout in eine Subshell einfügen und erfolgreich ausführen:

( timeout 10 <command> || true ) | wc -c

3
Einen fehlgeschlagenen Befehl erfolgreich ausführen? Oh, das sieht so böse aus: D
Erathiel

17
@Erathiel Willst du lächeln, während du böse bist? Versuchen Sie dies (es entspricht dem oben genannten):(timeout 10 <command> || :) | wc -c
Marco

1
Ich habe versucht, eine Unterschale zu verwenden, habe aber nicht daran gedacht, sie zum Erfolg zu führen. Ausgezeichnet!
P.Péter,

2

Kurz nach dem Posten hatte ich den Gedanken, Named Pipes für den Prozess zu verwenden:

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

Das scheint zu funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.