ubuntuusers.de

Elegante Umleitung komprimiert in eine Datei und gleichzeitig auf die Konsole

Status: Ungelöst | Ubuntu-Version: Xubuntu 20.04 (Focal Fossa)
Antworten |

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Ich bin auf folgende Wege gekommen (Zeile 1 und 13):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ vmstat -t 1 3 | tee $(0<&2 tty) | gzip -9 >| x.gz
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 4  0 202008 130452  79696 2358668   11   90  2260  1469 1572 2714 25  9 65  1  0 2022-04-30 11:29:41
 0  0 202008 125900  79696 2362372    0    0     0     0  943 1099  2  2 97  0  0 2022-04-30 11:29:42
 0  0 202008 127292  79696 2362372    0    0     0     0  945 1063  1  0 99  0  0 2022-04-30 11:29:43
$ gzip -dc x.gz 
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 4  0 202008 130452  79696 2358668   11   90  2260  1469 1572 2714 25  9 65  1  0 2022-04-30 11:29:41
 0  0 202008 125900  79696 2362372    0    0     0     0  943 1099  2  2 97  0  0 2022-04-30 11:29:42
 0  0 202008 127292  79696 2362372    0    0     0     0  945 1063  1  0 99  0  0 2022-04-30 11:29:43
$ vmstat -t 1 3 | tee >(gzip -9 >| x.gz)
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 3  0 202008 127628  79696 2361072   11   89  2240  1461 1562 2695 25  9 66  1  0 2022-04-30 11:29:53
 0  0 202008 123608  79696 2365036    0    0     0   208  994 1213  2  1 98  0  0 2022-04-30 11:29:54
 2  0 202008 125368  79696 2365080    0    0     0   280  940 1118  2  1 98  0  0 2022-04-30 11:29:55
$ gzip -dc x.gz 
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 3  0 202008 127628  79696 2361072   11   89  2240  1461 1562 2695 25  9 66  1  0 2022-04-30 11:29:53
 0  0 202008 123608  79696 2365036    0    0     0   208  994 1213  2  1 98  0  0 2022-04-30 11:29:54
 2  0 202008 125368  79696 2365080    0    0     0   280  940 1118  2  1 98  0  0 2022-04-30 11:29:55

Die erste Variante funktioniert auch mit der sh, für die zweite braucht man die bash oder eine andere Shell. Hat jemand noch eine elegantere Idee?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Wie wäre es damit (wenn es einem egal ist, dass die Ausgabe von vmstat auf stderr in der Konsole ankommt)?

vmstat -t 1 3 | tee -a /dev/fd/2 | gzip -9 > x.gz 

Damit spart man sich die Subshell bzw. die Process Substitution.

rklm Team-Icon

Projektleitung
(Themenstarter)

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

seahawk1986 schrieb:

Wie wäre es damit (wenn es einem egal ist, dass die Ausgabe von vmstat auf stderr in der Konsole ankommt)?

vmstat -t 1 3 | tee -a /dev/fd/2 | gzip -9 > x.gz 

Damit spart man sich die Subshell bzw. die Process Substitution.

Auch eine interessante Idee. Danke! So richtig toll finde ich aber keine von denen, die wir bisher gefunden haben. Mit explizitem Fifo wird es noch hässlicher:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ f=$(mktemp -u); mkfifo "$f"; gzip -9 <"$f" >|x.gz & vmstat -t 1 3 | tee -a "$f"; rm "$f"
[1] 5150
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 2  0  32960 473988 114840 2114140    1   10  1014   585 1128 2006 12  6 81  1  0 2022-05-01 12:10:10
 0  0  32960 470536 114840 2118388    0    0     0     0  919  980  1  1 97  0  0 2022-05-01 12:10:11
 0  0  32960 470536 114840 2117776    0    0     0     0  971 1033  1  1 99  0  0 2022-05-01 12:10:12
[1]+  Done                    gzip -9 < "$f" >| x.gz
$ gzip -dc x.gz 
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                CEST
 2  0  32960 473988 114840 2114140    1   10  1014   585 1128 2006 12  6 81  1  0 2022-05-01 12:10:10
 0  0  32960 470536 114840 2118388    0    0     0     0  919  980  1  1 97  0  0 2022-05-01 12:10:11
 0  0  32960 470536 114840 2117776    0    0     0     0  971 1033  1  1 99  0  0 2022-05-01 12:10:12

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Wenn die Datenmenge überschaubar ist und man die Ausgabe nicht live zeilenweise mitlesen können muss, könnte man auch die Reihenfolge umdrehen:

vmstat -t 1 3 | gzip -9 | tee x.gz | zcat 

Ansonsten würde ich das Problem für Shell-Ausgaben in ein kleines Python-Skript wegabstrahieren:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
import fileinput
import gzip
import sys

with gzip.open(sys.argv[1], 'wb', gzip._COMPRESS_LEVEL_BEST) as g:
   for line in fileinput.input([]):
       print(line, end='')
       g.write(line.encode())
vmstat -t 1 3 | ./gztee.py x.gz 

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9779

Wohnort: Münster

Wenn die Datenmenge überschaubar ist (und vermutlich ist sie es, denn sonst macht das Mitlesen keinen Sinn), dann kann sie auch einfach zwischenspeichern:

vmstat -t 1 3 | tee x ; gzip -9 $_ 

Und wenn die Datenmenge doch nicht überschaubar ist, dann macht eben das Mitlesen-Können keinen Sinn:

vmstat -t 1 3 | gzip -9 x.gz 

Und wenn man eigentlich nur das erfolgreiche Zippen überprüfen will, wäre der Vorschlag von seahawk1986 ideal.

rklm Team-Icon

Projektleitung
(Themenstarter)

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

seahawk1986 schrieb:

Wenn die Datenmenge überschaubar ist und man die Ausgabe nicht live zeilenweise mitlesen können muss, könnte man auch die Reihenfolge umdrehen:

vmstat -t 1 3 | gzip -9 | tee x.gz | zcat 

Auch interessant, allerdings liegt hier die Uneleganz darin, dass man eine überflüssige Operation hat (das Dekomprimieren).

Ansonsten würde ich das Problem für Shell-Ausgaben in ein kleines Python-Skript wegabstrahieren:

Das ist jetzt aber Kanonen auf Spatzen. Das würde ich dann natürlich in Ruby machen:

1
2
3
4
5
6
7
#!/usr/bin/ruby -p

BEGIN { require 'open3'; $o = Open3.pipeline_w(%w{gzip -c9}, out: ARGV.shift) }

$o.first.write($_)

END { $o.first.close; $o.last.first.join }

kB schrieb:

Wenn die Datenmenge überschaubar ist (und vermutlich ist sie es, denn sonst macht das Mitlesen keinen Sinn)

Das hat wenig mit der Menge an Daten aber viel mit der Geschwindigkeit der Ausgabe zu tun.

Danke für $_ - den kannte ich noch nicht.

Antworten |