大きなディレクトリを圧縮しようとしていますが、結果のファイルのサイズを正確に知りたいです。
私はdu
を使ってみました:
$ tar -cv dir | du -h -
du: cannot access '-': No such file or directory
次に、「-」のファイルバージョンを使用してみました。
$ tar -cv dir | du -h /dev/stdin
1.0K
この数値は正確ではないと確信しています。 stdinのサイズを取得するにはどうすればよいですか?
tl; dr:tar -cv dir | wc -c - | cut -d' ' -f 1 | awk '{print $1/1000"K"}'
du
は、実際にはファイル自体のサイズをカウントしません。カーネルにファイルシステムのクエリを要求するだけで、ファイルシステムはすでにファイルサイズを追跡しています。これがとても速い理由です。そのため、ファイルではなくストリームをカウントしているため、du
は機能しません。私の推測では、1.0K
はカーネルの/dev/std*
のハードコードされたサイズです。
解決策は、カーネルをクエリする代わりにバイト自体をカウントするwc -c
を使用することです。
$ tar -cv dir | wc -c
du -h
のような出力が必要な場合:
$ tar -cv dir | wc -c | awk '{print $1/1000"K"}'
awk
は、数値を人間が読める結果に変換します。
GNU tar
を使用すると、次のことができます。
tar --totals -c . >/dev/null
...出力は次のようになります...
Total bytes written: 5990400 (5.8MiB, 5.5GiB/s)
... stderr上。同様に、任意のtar(またはストリーム)を使用すると、dd
を使用してバイトカウントに関するレポートを配信できます。これはwc
よりも好ましい場合とそうでない場合がありますが、dd
のデフォルトは512バイトのブロックサイズで、これはtar
のブロックサイズと同じです。システムの PIPE_BUF が十分に大きければ、dd
のブロックサイズを拡張してtar
のレコードサイズ-20ブロック、つまり10240バイト。このような:
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
これはwc
よりも優れたソリューションを提供する場合と提供しない場合があります。
ただし、dd
とtar
の両方のユースケースで、実際にストリームを破棄する必要はありません。上記の/dev/null
にリダイレクトしますが、一部のファイルに簡単にリダイレクトでき、作成時のサイズに関するレポートを引き続き受信できます。
私はお勧めします:
tar cf - dir | wc -c
単純なc
(先頭に-
は不要)を使用してtar
アーカイブを作成し、f
は出力ファイルを指定し、-
はstdoutになります。 (サイズだけが必要で、その下に多くのファイルがある場合dirパフォーマンス上の理由から、tar
のv
を省略してもかまいません。)
質問の文言はtar ... | wc -c
上記の回答。私はもともと、tarファイルの作成中にサイズを報告してほしい(おそらくtarの出力がネットワークリンク経由でパイプ処理されていたのではないか?).
その場合は、pv
-パイプビューアをお勧めします。私はそれへの言及を見ましたが、まだそれを試す機会がありませんでした。
参照