timeout, rupture de tuyaux et wc

20

J'ai eu l'idée de comparer rapidement certains programmes de décompression. Par exemple pour gz, je lancerais la commande:

timeout 10 zcat foo.gz | wc -c

Ce qui mesurerait la quantité de données que le décompresseur pourrait extraire en 10 secondes.

Le seul problème est que cela ne fonctionne pas: comme zcat est tué, wc est également tué, donc je n'ai pas le nombre d'octets, juste un Terminatedmessage.

Donc, la question est: existe-t-il un moyen d'obtenir le nombre de wc , soit en bloquant le signal d'une manière ou d'une autre, soit en utilisant wc qui imprime un résultat même quand il obtient un signal de terme.


Bien sûr, il existe des alternatives:

  1. Écriture dans un fichier temporaire:
    timeout 10 zcat foo.gz > /dev/shm/x ; du -sb /dev/shm/x ; rm -r /dev/shm/x Le problème avec cela est qu'il utilise beaucoup de mémoire et peut également avoir une baisse des performances.

  2. Utiliser ulimit à la place:
    ulimit -t 10; zcat foo.gz | wc -c
    cela fonctionne également, mais ne mesure que le temps processeur, donc le ralentissement dû aux E / S (par exemple parce que la compression est pire et que davantage d'octets doivent être lus sur le disque) n'est pas mesuré.

  3. Créer des fichiers de test plus petits:
    Eh bien, cela peut bien sûr fonctionner et peut être la meilleure solution. Cependant, cela crée beaucoup de fichiers temporaires.

P.Péter
la source
6
Alors que je lisais "casser les tuyaux et les toilettes", j'ai d'abord pensé que vous aviez des problèmes de plomberie!
dr01

Réponses:

21

Vous pouvez placer la commande timeout dans un sous-shell et la faire réussir:

( timeout 10 <command> || true ) | wc -c
Marco
la source
3
Faire réussir une commande qui a échoué? Oh, ça a l'air si mal: D
Erathiel
17
@Erathiel Tu veux sourire tout en étant méchant? Essayez celui-ci (c'est équivalent à ce qui précède):(timeout 10 <command> || :) | wc -c
Marco
1
J'ai essayé d'utiliser un sous-shell, mais je n'ai pas pensé à le faire réussir. Excellent!
P.Péter
2

Juste après la publication, j'ai pensé à utiliser des canaux nommés pour le processus:

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

Cela semble fonctionner.

P.Péter
la source