Wie kann ich die Größe von stdin bekommen?

8

Ich bin dabei, ein großes Verzeichnis zu komprimieren, und ich möchte wissen, wie groß die resultierende Datei genau sein wird.

Ich habe versucht du:

$ tar -cv dir | du -h -
du: cannot access '-': No such file or directory

Dann habe ich versucht, die Dateiversion von '-' zu verwenden:

$ tar -cv dir | du -h /dev/stdin
1.0K

Ich bin sicher, dass diese Zahl nicht korrekt ist. Wie kann ich die Größe von stdin bekommen?

strugee
quelle

Antworten:

10

tl; dr :tar -cv dir | wc -c - | cut -d' ' -f 1 | awk '{print $1/1000"K"}'

duzählt eigentlich nicht die Größe der Datei selbst. Der Kernel wird lediglich aufgefordert, das Dateisystem abzufragen, das bereits die Dateigröße verfolgt. Deshalb ist es so schnell. Aus diesem Grund dufunktioniert die Tatsache, dass Sie einen Stream und keine Datei zählen, nicht. Ich vermute, dass dies 1.0Keine fest codierte Größe für /dev/std*den Kernel ist.

Die Lösung besteht darin wc -c, die Bytes selbst zu zählen, anstatt den Kernel abzufragen:

$ tar -cv dir | wc -c

Wenn Sie eine Ausgabe ähnlich der du -hfolgenden wünschen :

$ tar -cv dir | wc -c | awk '{print $1/1000"K"}'

Das awkmacht die Zahl zu einem lesbaren Ergebnis.

strugee
quelle
8
Beachten Sie, dass Sie den nachfolgenden Befehl auch nicht benötigen , wenn Sie wcdas Überflüssige einfach weglassen . -cut
Janis
1
1.0K ist die Blockgröße von stdin.
Cody Allan Taylor
6

Mit GNU können tarSie einfach Folgendes tun:

tar --totals -c . >/dev/null

... was die Ausgabe wie ...

Total bytes written: 5990400 (5.8MiB, 5.5GiB/s)

... auf stderr. In ähnlicher Weise mit jedem Teer (oder Strom) können Sie verwenden ddeinen Bericht über Bytezählwerte zu liefern. Dies kann vorzuziehen sein oder nicht wc, ist jedoch ddstandardmäßig auf eine Blockgröße von 512 Bytes eingestellt - was mit der tarBlockgröße identisch ist . Wenn die PIPE_BUF Ihres Systems groß genug ist, können Sie die ddBlockgröße sogar erweitern , um sie an die Datensatzgröße anzupassentar - 20 Blöcke oder 10240 Byte. So was:

tar -c . | dd bs=bx20 >/dev/null
585+0 records in
585+0 records out
5990400 bytes (6.0 MB) copied, 0.0085661 s, 699 MB/s

Dies kann eine leistungsfähigere Lösung bieten als oder nicht wc.

Sowohl im ddals auch im tarAnwendungsfall müssen Sie den Stream jedoch nicht wirklich entsorgen. Ich leite nach /dev/nulloben um - aber ich hätte genauso gut zu einer Datei umleiten können und trotzdem den Bericht über seine Größe zum Zeitpunkt des Schreibens erhalten.

mikeserv
quelle
Falls die Datei auf die Festplatte geschrieben wird, kann die Größe nicht separat bestimmt werden, da diese Informationen in der Datei gespeichert werden. (+1) für den erwarteten Leistungsgewinn von dd(im Vergleich zu wc).
Janis
1
@Janis - möglicherweise im einfachsten Fall wahr - aber stellen Sie sich vor, dass dddie Ausgabe an einen Kompressor weitergeleitet wird - und aus irgendeinem Grund ist es wünschenswert, sowohl die Rohgröße des Archivs als auch die komprimierte zu kennen. Es ist auch nützlich, sofort einen Bericht über die Anzahl der Datensätze zu erhalten - dies tarist nicht nur ein Archiv, sondern ein Stream-Format. Es kann auf andere Weise verwendet werden, als nur in einer Gruppe von Dateien in einer anderen Datei zu speichern. Es ist oft nützlich, um einen Stream zu blockieren, bevor Sie ihn ändern. An jeder dieser Datensatzgrenzen befindet sich ein ganzer Block von NULs.
Mikeserv
5

Ich würde vorschlagen:

tar cf - dir | wc -c

Ein einfaches c(kein Leading -erforderlich) wird verwendet, um ein tarArchiv zu erstellen , fgibt eine Ausgabedatei an und gibt an, -dass es stdout ist . (Beachten Sie, dass , wenn Sie wollen einfach nur die Größe und es gibt viele Dateien unter dir Sie können eher auslassen tar‚s vaus Leistungsgründen.)

Janis
quelle
@mikeserv; Ich erinnere mich, dass ich tarin der Vergangenheit mit s gearbeitet habe, wo die Angabe einer TAR-Datei (also fund -) erforderlich war. - Ich habe es gerade nachgeschlagen. ohne f -die als Standard tarangenommen /etc/mt0.
Janis
1
Ich habe es in einem Buch nachgeschlagen, das ich damals als Handbuch verwendet habe, und ich denke, es basiert auf SysV R4. Nur wenige Leute erinnern sich sicher daran, was /etc/mt0eigentlich bedeutet - "Magnetband" ;-) Ich würde mich interessieren, wie sich Solaris tarverhält (weil Solaris eines der zeitgenössischen Betriebssysteme ist, von denen bekannt ist, dass sie noch sehr alte Sachen enthalten /bin).
Janis
@mikeserv; PS: In dem Buch wird das "UNIX Programmers Manual Volumes 1, 2A, 2B" von AT & T als Quelle erwähnt (jedoch kein manuelles Datum oder keine UNIX-Veröffentlichungsversion; es muss jedoch aus den frühen 1980er Jahren, 1983 oder so stammen).
Janis
Haben Sie schon einmal gesehen , dies ? Unabhängig - aber ich habe es heute gerade gefunden und dachte, es könnte dir gefallen.
Mikeserv
Ich verstehe nicht ganz, wie sich diese Antwort von meiner unterscheidet. ist es das Vorhandensein der -fFlagge zu tar?
strugee
1

Der Wortlaut Ihrer Frage eignet sich für die tar ... | wc -cobigen Antworten. Ich habe Ihre Frage ursprünglich mit der stillen Annahme gelesen, dass die Größe beim Erstellen der TAR-Datei gemeldet werden soll (möglicherweise wurde die Ausgabe von TAR dann über eine Netzwerkverbindung weitergeleitet?).

In diesem Fall würde ich vorschlagen pv- Pipe Viewer. Ich habe einen Hinweis darauf gesehen, aber noch keine Chance gehabt, damit zu spielen.

Verweise

Jeff Schaller
quelle