24時間ごとに1つずつstdoutに動的に生成される大容量ファイルがあります。これらのファイルをテープに徐々に保存したいと思います。可能であれば、複数のテープにまたがる可能性のある単一のアーカイブに保存したいと思います。
Tarはアーカイブに追加し、次のテープをロードする機能を内蔵しているため、テープ管理に適しています。しかし、標準入力からデータを受け入れるのは非常に悪いです。私が何をしても、最終的にアーカイブの内容の代わりに特別なファイル(リンクまたは名前付きパイプ)がアーカイブに書き込まれます。
以下は私が試したサンプルコマンドです。最初の日には新しいアーカイブを作成します。
ln -s /dev/stdin day1 # or use the --transform option of tar
data_generator | tar -c -h -M -f /dev/nst0 -H posix -F 'mtx -f /dev/sch0 next' day1
翌日、-cを-Aに変更して、新しいストリームをtarアーカイブに追加された新しいファイルに保存し、必要に応じて新しいテープをロードしようとします。
data_generator | tar -A -h -M -f /dev/nst0 -H posix -F 'mtx -f /dev/sch0 next' day2
私が言ったように、私がアーカイブで見つけたすべては、名前付きパイプ(-hを含む)またはシンボリックリンク(-hを除く)でした。
私が試したアイデアのいくつかはうまくいきませんでした。
split
代わりに使用するtar
のはあまりにも基本的なので不可能です。事前定義されたディメンションにのみ分割することができます(テープの先頭から始めないとうまくいきません)、圧縮できないアーカイブに他の日付を結合することはできません。 Tarはデータやテープサイズを知る必要はなく、書き込みエラーが発生した場合にのみ新しいテープに切り替えます。- 私はcpio、star、darに関するマニュアルを読んだ。私は彼らがタールよりもパイプをよりよく扱うとは思わない。
どんなヒントでもくれてありがとう。
編集:書き込みを始める前にファイルサイズを知る必要があるため、tarは不可能だと思い始めました。実際、拡張可能なアーカイブの場合、コンテンツの前にサイズを書き留めておくと、追加が非常に面倒です。
答え1
一晩休んだ後、読みたいデータの量を事前に知っていれば(私も知っています)、少しPythonがあればこれを行うことができることがわかりました。この単純なプログラムはstdinから1MBのデータを読み込み、「filename.dat」にカプセル化されたtarアーカイブでstdoutにデータを書き込みます。
#!/usr/bin/env python3
import tarfile
with open("/dev/stdout", "ab") as outf:
tar = tarfile.open(fileobj=outf, mode="w")
with open("/dev/stdin", "rb") as inf:
filesize=1048576 # 1MB
tarinfo = tarfile.TarInfo(name="filename.dat")
tarinfo.size=filesize
tar.addfile(tarinfo, fileobj=inf)
# -- end program tarpipe.py ---
たとえば、次のプログラムを使用すると、1MBのランダムなデータをインポートしてtarアーカイブに転送できます。
cat /dev/urandom |./tarpipe.py > daily.tar
結果のアーカイブには「filename.dat」という 1MB ファイルが含まれています。
tarアーカイブが機能するため、毎回ファイル名を変更する限り、それを追加(>>)して拡張することができます(そうしないと、解凍するとファイルが上書きされます)。
テープの変更を管理するためにローカルでこれを行うことができるmbbufferを介して出力をパイプできます。