.gzファイルを.xzファイルに安全に変換する方法


5

現在gzip圧縮されているいくつかの巨大なファイルがあり、xzにしたいと思います。これを行うためのスクリプトをセットアップしたいのですが、データを失わないように注意してください。つまり、xzバージョンが正しく作成されていない限り、gzippedバージョンを削除しないでください。これらは大きなファイルなので、最初にファイルをディスクに解凍しないことも好みます。私はパイプset -o pipefail; gzip -dc file.gz | xz > file.xz && rm file.gzが私が望むものに近いかもしれないと考えていました。これを行う正しい方法は何ですか?これにより、最終ファイルを削除する前に発生した障害を確実にキャッチできますか?


私はあなたので使用し&&ない||でくださいと思います&& rm file.gz。それ以外の場合は||、失敗しfile.gzxz場合でも削除されます。これは望ましくありません。
ダンD.

固定もちろん@Dan D.あなたは正しい、
ニシキヘビ隠喩

回答:


9

SHA1合計(ハッシュが一致する場合にファイルが一致すること、およびファイルが一致しない場合にハッシュが一致しないことを数学的に非常に確実に保証)を追加すると、データ整合性の尺度が追加され、ディスクサブシステムが書き込み中に(サイレント)ミスをした可能性があります。サイレント破損はまれですが、発生した場合は陰湿です。

もちろん、読み取り中にランダムなエラーが発生した場合、結果が混乱する可能性がありますが、その場合、合計は非常に高い確実性でとにかく一致しません。言い換えれば、システムが破損している場合(RAMまたはディスクが間違ったビット/反転ビット/破損したデータを生成している場合)、シンプル&&が成功する可能性がある場所でこれは失敗し、破損したデータでこのrm行に到達する可能性はゼロになります小さい(ほとんどのエラーはランダムな方法でデータを破損する傾向があるため、リードバック中にランダムな変更がSHA1でハッシュ衝突を引き起こす可能性は驚くほど小さいです。)

#!/bin/bash
set -e
set -o pipefail
ORIGSUM=$(gzip -dc file.gz | tee >(xz > file.xz) | sha1sum)
NEWSUM=$(unxz -c file.xz | sha1sum)
if [ "${ORIGSUM}" = "${NEWSUM}" ]; then rm file.gz; fi

set -e同じようにすぐにシェルスクリプト出口を作る任意のスクリプトの行は0以外の終了コードを返します。

その後、我々は、使用teeするファイルの非gzip圧縮された出力をコピーするコマンドを両方xzの圧縮機、およびへのsha1sumプログラム。sha1sumg1アーカイブに含まれる元のデータのSHA1合計を、sha1sumプログラムに一時的に解凍することにより計算します。sha1sumプログラムはデータを読み取り、合計を計算してからデータを破棄します。を使用することによりtee、ファイルを解凍するCPUコストを1回支払うだけで済みます。

次に、追加の計算コストの高いステップを実行して(超追加検証用)、ファイルのxz圧縮を(一時的にストリームに)ストリップし、sha1sumにパイプして、「新しいファイル」SHA1合計を取得します。

次に、2つの合計を比較し、それらが等しい文字列ではない場合、またはそれらのいずれかまたは両方が長さゼロの場合、スクリプトエラー(これはのおかげで終了します)を取得するset -eか、ファイルが削除されました。else必要に応じて、ユーザーフレンドリーなエラー処理の句を実装できますが、この重要なスクリプトは、コマンドをインタラクティブに実行するユーザーにとってあまり有益ではありませんが、非常に安全です。

最後に、file.gz唯一のリンク解除される場合に限り、非圧縮の内容file.gzとは、file.xzハッシュが何か悪いのオッズは何だろう間違っている(確実性の天文学的に高い程度で、計算された時点で正確に同一であり、 1に1のように、その後に300個のゼロがある)その時点でこのスクリプトの終了後にデータが破損することを心配するだけです。;)


性能

このスクリプトは、実行する部分を除き、問題の元のスクリプトとほぼ同じ速度で実行されますunxz。幸いなことに、LZMAからの圧縮解除は非常に高速で、通常のZipとほぼ同じ速度で、LZMA への圧縮よりも1桁高速です。あなたは高速CPUを持っており、ファイルが十分に小さい場合には、これは追加しないでくださいあまりにもスクリプトに多くのランタイムをしていますが、パフォーマンス上のデータの整合性を重視すれば、それは明確な勝利です。


クレジットが支払われる場合のクレジット

StackOverflowに関するこの回答は、このスクリプトの作成に大いに役立ちました。


これは、圧縮が正しく機能し、実行時間をほぼ同じに保つための非常に良い方法です。そして、はい、私はこれらの操作のいくつかを計りました、そして、xzステップはunxzステップより桁違いに遅いので、私はその部分について心配していません。
pythonicメタファー14年

追加する必要があります、ECC RAMを搭載し、btrfsまたはなどの組み込みの整合性チェックを備えたファイルシステムを実行しているシステムでzfsは、オペレーティングシステムとハードウェアがすでに連携して私のsha1sumテストと非常によく似た処理を実行しているため、このような構成では、このスクリプトからsha1sumチェックを削除するリスクはごくわずかです。一方、非ECC RAMと組み込みの整合性を持たないファイルシステムがある場合、これによりスクリプトが大幅に安全になります。
allquixotic
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.