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
。私も別のファイルで試してみました。
pv
withを使ってみましたが、cat
出力がよく出ますね。md5sum
。
答え1
このpv
ユーティリティは「エキゾチックcat
」です。つまり、pv
使用しなければならないほとんどの状況で使用できるという意味ですcat
。
cat
with を使用すると、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を返します。監視中のプロセスが終了するとすぐに終了します。md5sum
pv
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行を生成するという事実と、バイトの代わりに行を計算する行モードがあるという事実を利用しますmd5sum
。pv
このモードでは、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
コメントやその他の回答ですでに指摘したように:
- 出力(チェックサムとファイル名)
pv
のみがパイピングされるため、進行状況バーには読み取っているデータ量は表示されません。md5sum
pv
md5sum
- 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/* | sort
がmd5sum 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
出力と出力が切り離されます。とにかく上記のコードを追加し、結果が正しく機能していることを確認できます。pv
md5sum
| sort
done
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
:ラベルに分岐)、エスケープをキャンセルする必要があることを示します。どちらの場合も、パターンスペースは終了前に標準出力として印刷されます()(このオプションは自動印刷を無効にします)。x
md5sum -c
p
-n