md5sumでpvを使う

md5sumでpvを使う

md5sum以下を使用して、pv同じディレクトリにある4GiBファイルを確認しました。

md5sum dir/* | pv -s 4g | sort

コマンドは約28秒で正常に完了しますが、pvすべてのエラーが出力されます。以下は、全体に表示される出力タイプです。

219 B 0:00:07 [ 125 B/s ] [>                                ]  0% ETA 1668:01:09:02

-s 4gなしで同じです| sort。私も別のファイルで試してみました。

pvwithを使ってみましたが、cat出力がよく出ますね。md5sum

答え1

このpvユーティリティは「エキゾチックcat」です。つまり、pv使用しなければならないほとんどの状況で使用できるという意味ですcat

catwith を使用すると、md5sum単一ファイルのMD5チェックサムを計算できます。

cat file | md5sum

またはpv

pv file | md5sum

md5sumただし、残念ながら、この方法ではファイル名を出力に正しく挿入することはできません。

pv幸運にも本物fancy cat、一部のシステム(Linux)では可能です。よりデータが別のプロセスを介して渡されています。これは、-d他のプロセスのプロセスIDとともに、対応するオプションを使用して行われます。

これは、次のことができることを意味します。

md5sum dir/* | sort >sums &
sleep 1
pv -d "$(pgrep -n md5sum)"

これにより、プロセスpvを表示できますmd5sum。これは、バックグラウンドで実行されているプログラムが正しく起動できるsleepようにするためです。md5sumあなたが所有している最後pgrep -n md5sumに開始されたプロセスのPIDを返します。監視中のプロセスが終了するとすぐに終了します。md5sumpv

pvこの特定の実行方法を数回テストした結果、通常はうまく機能しているようですが、時には次のファイルに切り替えながらmd5sum何も出力しないようです。時にはシェルから偽のバックグラウンドタスクを作成するようです。

走るのが一番安全だと思います。

md5sum dir/* >sums &
sleep 1
pv -W -d "$!"
sort -o sums sums

この-Wオプションを使用すると、実際のデータが送信されるのを待ちますが、pv常に確実に動作するわけではありません。

答え2

パイプを介して提供されるデータは、md5sum処理中のファイルのデータではなく、md5sum各ファイルに対して1行(MD5ハッシュ、スペース2つ、ファイル名)で構成される出力です。これを事前に知っているので、pvそれに応じて通知を送信して正確な進行状況インジケータを表示できます。これを行う方法は2つあります。

最初に推奨される方法(Frosschutzが提案)は、処理された各ファイルが1行を生成するという事実と、バイトの代わりに行を計算する行モードがあるという事実を利用しますmd5sumpvこのモードでは、pv進行状況バーはスループットで改行文字が見つかった場合にのみ移動されます(つまり、各ファイルによって完了)md5sum。 Bashの最初の方法は次のとおりです。

set -- *.iso; md5sum "$@" | pv --line-mode -s $# | sort

set処理するファイルの位置パラメータを設定する機能を組み込み(シェルに拡張された*.isoシェルモード)、これらのmd5sumファイルを処理するように指示し($@位置引数に拡張)、pvラインモードでは、ラインがファイルとして処理/出力されるたびに進行インジケータが移動しますmd5sum。特別なシェル引数は位置引数の数に拡張されるため、pv予想できる行の総数()を知っていることは注目に値します。-s $#$#

2番目の方法は行ベースではなくバイトベースです。これはmd5sum不必要に複雑ですが、他のプログラムでは行を生成しませんが、連続データを生成できるため、このアプローチはより実用的かもしれません。私はmd5sumそれを説明します。アイデアは、md5sum(または他のプログラム)がそれを知らせるために生成し、使用するデータの量を計算することですpv。 Bashでは、次のように見えます。

os=$(( $( ls -1 | wc -c ) + $( ls -1 | wc -l ) * 34 ))
md5sum * | pv -s $os | sort

最初の行は出力サイズ(os)の推定値を計算します。最初の項目はファイル名(改行を含む)をエンコードするために必要なバイト数、2番目の項目はMD5ハッシュ(それぞれ32文字)をエンコードするために使用されるバイト数です。 、スペースを2つ追加します。 2行目では、最大100%の正確な進行状況インジケータ(完成したmd5summedファイルに基づいて更新)を表示できるように、pv予想されるデータ量をバイト単位で通知します。os

明らかに、これら2つの方法は、処理するファイルが複数ある場合にのみ実用的です。また、出力はプログラムが基本データを処理するのにかかるmd5sum時間とは関係がないため、md5sum進行状況インジケータが多少誤解を招くと考えられます。たとえば、2番目のアプローチでは、名前が最も短いファイルが実際には最も大きい場合でも、最低の進行状況更新を生成します。その後、すべてのファイルのサイズと名前が似ている場合は問題になりません。

答え3

各ファイルの進行状況を確認する汚れた方法は次のとおりです。

for f in iso/*
do
    pv "$f" | (
        cat > /dev/null &
        md5sum "$f"
        wait
    )
done

外観:

4.15GiB 0:00:32 [ 130MiB/s] [================================>] 100%            
0db0b36fc7bad7b50835f68c369e854c  iso/KNOPPIX_V7.6.1DVD-2016-01-16-EN.iso
 792MiB 0:00:06 [ 130MiB/s] [================================>] 100%            
97537db63e61d20a5cb71d29145b2937  iso/archlinux-2016.10.01-dual.iso
 843MiB 0:00:06 [ 129MiB/s] [================================>] 100%            
1b5dc31e038499b8409f7d4d720e3eba  iso/lubuntu-16.04-desktop-i386.iso
 259MiB 0:00:02 [ 130MiB/s] [=========>                        ] 30% ETA 0:00:04
...

今これはいくつかの仮定をします。まず、データを読み取る方がデータをハッシュするよりも遅くなります。第二に、OSはI / Oをキャッシュするため、完全に独立したリーダーでもデータはpv(物理的に)2回読み取られませんmd5sum

この汚れたハッキン​​グの良いことは、1つのファイルではなくすべてのデータの進行状況バーを作成するように簡単に調整できることです。そして、事実の後に出力をソートするなど、奇妙なことを続けます。

pv iso/* | (
    cat > /dev/null &
    md5sum iso/* | sort
    wait
)

姿(進行中):

15.0GiB 0:01:47 [ 131MiB/s] [===========================>      ] 83% ETA 0:00:21

様子(完了):

18.0GiB 0:02:11 [ 140MiB/s] [================================>] 100%            
0db0b36fc7bad7b50835f68c369e854c  iso/KNOPPIX_V7.6.1DVD-2016-01-16-EN.iso
155603390e65f2a8341328be3cb63875  iso/systemrescuecd-x86-4.2.0.iso
1b5dc31e038499b8409f7d4d720e3eba  iso/lubuntu-16.04-desktop-i386.iso
1b6ed6ff8d399f53adadfafb20fb0d71  iso/systemrescuecd-x86-4.4.1.iso
25715326d7096c50f7ea126ac20eabfd  iso/openSUSE-13.2-KDE-Live-i686.iso
...

今これはハッカーのためのものです。正しい解決策については、他の答えを確認してください。 ;-)

答え4

コメントやその他の回答ですでに指摘したように:

  1. 出力(チェックサムとファイル名)pvのみがパイピングされるため、進行状況バーには読み取っているデータ量は表示されません。md5sumpvmd5sum
  2. 4GBは確かに大きすぎますね。また、pvインポートするファイルのサイズを提供(手動で使用-s)することも不便です。

ファイルの内容をパイピングしpvてから再入力すると、進行状況md5sumバーが表示されますが、ファイル名は失われます。

このコードは、意味のある進行状況バーとチェックサムを含むファイル名の両方を持つエレガントな方法ではありません。

#!/bin/sh

for file in "$@"; do
    pv -- "$file" |
    md5sum |
    sed 's/-$//' |
    printf '%s%s\n' "$(cat -)" "$file"
done

スクリプトは次のように呼び出されます。

./script dir/*

もちろん、呼び出すためにパスを入力する必要がないように(またはパスを追加することなく関数として宣言できますPATH):

function pvsum () {
    for file in "$@"; do
        pv -- "$file" |
          md5sum |
          sed 's/-$//' |
          printf '%s%s\n' "$(cat -)" "$file"
    done
}

これにより、コマンドpvsum dir/* | sortmd5sum dir/* | pv -s <size> | sort

出力:

$ ./testscript testdir/*
4.00GiB 0:00:09 [ 446MiB/s] [==============================>] 100%            
9dab5f8add1f699bca108f99e5fa5342  testdir/file1
1.00GiB 0:00:02 [ 447MiB/s] [==============================>] 100%            
06a738a71e3fd3119922bdac259fe29a  testdir/file2

できること:

  • 与えられたファイルと各ファイルを繰り返します。
    • pvファイルをにパイプしてデフォルトの進行md5sum状況バーを表示します。
    • sed-印刷を削除するためにmd5sum(stdinから読み取る)出力を消費に適したものにしようとしますmd5sum -c(ありがとう)フロストスーツこれを指摘してください)1
    • ファイル名の後にチェックサムを標準出力として印刷します。

についてsort

予想される結果が何なのかよく分からないので無視しました。pv進行状況バーが標準エラーに書き込まれるため、すべてをパイピングすると、sort出力と出力が切り離されます。とにかく上記のコードを追加し、結果が正しく機能していることを確認できます。pvmd5sum
| sortdone


1md5sum -cファイル名に改行文字が含まれている場合、上記のコードの出力が正しくありません。改行を処理することは可能ですが、一部のバージョンはmd5sumこれに関して異なる動作をします(たとえば、回答を参照)。この問題)、一般的な解決策を策定するのは簡単ではありません(そしてこの答えの範囲外です)。

最新バージョンを使用していると仮定すると、md5sumこの問題を解決する試みは次のとおりです。

for file in "$@"; do
    pv -- "$file" |
    md5sum |
    sed 's/-$//' |
    printf '%s%s\n' "$(cat -)" "$file" |
    sed -n 'H; 1h; $!d; g; s/\\/\\\\/g; s/\n/\\n/g; t x; p; q; :x s/^/\\/; p;'
done

唯一の追加である最後は次のsedとおりです。

  • 現在のファイルの完全な入力、チェックサム、名前をパターン空間に入れます。新しい行を含めることができるからです。H新しい行と現在のパターンスペースを予約済みスペースに追加し、最初の行に対してのみ前を1h上書きします。H改行は追加されません。$!d現在の行が最後の行でない場合、新しいループが開始されます。g予約済みスペースの内容がパターンスペースに配置されます。
  • \生成されたパターン空間からバックスラッシュをエスケープするには、バックスラッシュ()を使用します。
  • \n結果パターン空間の改行に置き換えられます。
  • バックスラッシュがチェックサムの先頭に追加され、少なくとも1つのバックスラッシュまたは改行文字が置き換えられた場合(t x:ラベルに分岐)、エスケープをキャンセルする必要があることを示します。どちらの場合も、パターンスペースは終了前に標準出力として印刷されます()(このオプションは自動印刷を無効にします)。xmd5sum -cp-n

関連情報