同じディレクトリにあるファイルの4 GiBを確認するためにpv
とともにmd5sum
を使用しました:
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
をcat
とともに使用してみましたが、出力は問題なかったため、問題はmd5sum
が原因であるようです。
pv
ユーティリティは「ファンシーcat
」です。つまり、pv
を使用するほとんどの状況でcat
を使用できます。
cat
をmd5sum
とともに使用すると、単一ファイルのMD5チェックサムを次のように計算できます
cat file | md5sum
または、pv
を使用して、
pv file | md5sum
残念ながら、これではmd5sum
が出力にファイル名を適切に挿入することができません。
幸いなことに、pv
はreallyファンシーcat
であり、一部のシステム(Linux)ではwatch別のプロセスを通過した。これは、その-d
オプションを他のプロセスのプロセスIDとともに使用することによって行われます。
つまり、次のようなことができます
md5sum dir/* | sort >sums &
sleep 1
pv -d "$(pgrep -n md5sum)"
これにより、pv
がmd5sum
プロセスを監視できるようになります。 sleep
は、バックグラウンドで実行されているmd5sum
が適切に起動できるようにするためにあります。 pgrep -n md5sum
は、所有している最後に開始されたmd5sum
プロセスのPIDを返します。 pv
は、監視しているプロセスが終了するとすぐに終了します。
私はpv
を実行するこの特定の方法を数回テストしましたが、それは一般的にはうまく機能しているようですが、md5sum
が次のファイルに切り替えると、何も出力されなくなる場合があります。時々、それはシェルで偽のバックグラウンドタスクを生み出すようです。
おそらくそれを次のように実行するのが最も安全でしょう
md5sum dir/* >sums &
sleep 1
pv -W -d "$!"
sort -o sums sums
-W
オプションは、実際のデータが転送されるまでpv
を待機させますが、これも常に確実に機能するとは限りません。
パイプを介して供給しているデータは、md5sum
が処理しているファイルのデータではなく、md5sum
出力であり、すべてのファイルについて、MD5-ハッシュ、2つのスペース、およびファイル名。これは事前にわかっているので、それに応じてpv
に通知し、正確な進行状況インジケーターを表示できるようにすることができます。これには2つの方法があります。
最初の推奨される方法(frostschutzが推奨)は、md5sum
が処理済みファイルごとに1行を生成することと、pv
がバイトではなく行をカウントする行モードを使用することを利用しています。このモードでは、pv
は、スループットで改行が検出されたとき、つまりmd5sum
で終了したファイルごとにのみ、進行状況バーを移動します。 Bashでは、この最初のメソッドは次のようになります。
set -- *.iso; md5sum "$@" | pv --line-mode -s $# | sort
set
ビルトインは、位置パラメータを処理するファイルに設定するために使用されます(*.iso
シェルパターンはシェルによって展開されます)。次に、md5sum
はこれらのファイルを処理するように指示され($@
は定位置パラメーターに展開されます)、行モードのpv
は、ファイルが処理されるたびに、進行状況インジケーターを移動します/行md5sum
によって出力されます。特に、特別なシェルパラメータ-s $#
は位置引数の数に拡張されるため、pv
には、予想される行の総数($#
)が通知されます。
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行目では、予想されるデータ量がpv
バイトであることをos
に伝え、100%までの正確な進行状況インジケーターを表示できるようにします(このインジケーターは、終了したmd5summedごとに更新されますファイル)。
明らかに、どちらの方法も、複数のファイルを処理する場合にのみ実用的です。また、md5sum
の出力はmd5sum
プログラムが基礎となるデータの処理に費やす必要のある時間とは関係がないため、進行状況インジケータは誤解を招く可能性があると見なされる場合があることに注意してください。たとえば、2番目の方法では、実際にサイズが最も大きくても、最も短い名前のファイルの進行状況の更新が最も少なくなります。繰り返しになりますが、すべてのファイルのサイズと名前が同じであれば、これはそれほど重要ではありません。
ファイルごとに進行状況を取得するための汚いハックは次のとおりです。
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
とmd5sum
は完全に独立したリーダーであるにもかかわらず、データが(物理的に)2回読み取られることはありません。
このようなダーティでダーティなハックのいいところは、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
...
さて、それはハックです。適切な解決策については、他の回答を確認してください。 ;-)
コメントやその他の回答ですでに指摘したように:
pv
のみmd5sum
の出力にチェックインしています:チェックサムとファイル名。したがって、pv
のプログレスバーは、md5sum
が読み取っているデータの量を表示できません。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
(標準入力から読み取っている)を削除するために使用されます。これはまた、出力をmd5sum -c
で使用するのに適したものにしようとします(これを指摘してくれた frostschutz に感謝します)1。sort
について:
期待される結果がわからないので無視しました。 pv
は進行状況バーを標準エラーに書き込むため、すべてをsort
にパイプすると、pv
の出力がmd5sum
の出力から切り離されます。
とにかく、上記のコードのdone
の後に| sort
を追加するだけで、結果に問題がないかどうかを確認できます。
1 上記のコードからの出力は、ファイル名に改行が含まれている場合、md5sum -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
で置き換えます。t x
:ラベルx
への分岐)、チェックサムの先頭にバックスラッシュが追加され、md5sum -c
に何かを通知するエスケープしないでください。それ以外の場合は単に終了します。どちらの場合も、終了する直前にパターンスペースを標準出力に印刷(p
)します(オプション-n
は自動印刷を無効にします)。md5sum
のために「ファンシーキャット」pv
を飼いならすことを楽しんでいます:-)usage
出力が表示されます。".* *"
)... OK
pv
のプロセスビュー出力は{画面/ターミナルウィンドウ}に残りますpv
プロセスがあり、1つはグローバルファイル、各ファイルは1つ、グローバルpv
は「ファイルのみをカウント」し、もう1つは転送されるデータの速度と量を測定します私はmd5summer
という名前を使用し、シェルスクリプトを実行可能にして、それをPATHのディレクトリに配置します(私の~/bin
ディレクトリ、/usr/local/bin
を好むかもしれません)。
#!/bin/bash
# date sign comment
# 20190119 sudodus created md5summer version 1.0
if [ "$1" == "-v" ]
then
verbose=true
shift
else
verbose=false
fi
if [ $# -ne 1 ]
then
echo "Usage: $0 [-v] <pattern>"
echo "Example: $0 '*.iso' # notice the quotes"
echo " $0 -v '*.iso' # verbose"
exit
fi
tmpstr=$(find $1 -maxdepth 0 -type f 2> /dev/null)
if [ "$tmpstr" == "" ]
then
echo "No such file '$1'. Try another pattern!"
exit
fi
tmpdir=$(mktemp -d)
tmpfil="$tmpdir/fil1"
tmpfi2="$tmpdir/fil2"
resetvid="\0033[0m"
prev2line="\0033[2F"
next2line="\0033[2E"
sln=1
cln=0
cnt=0
for i in $1
do
if test -f "$i"
then
cln=$((cln+1))
tmp=$(find -L "$i" -printf "%s")
cnt=$((cnt+tmp))
fi
done
echo "
number of files = $cln
total file size = $cnt B ~ $(($cnt/2**20)) MiB
"
for i in $1
do
if test -f "$i"
then
tmpnam=$(echo -n "$i")
tmpsum=$(< "$i" pv -ptrbs "$cnt" | md5sum)
sleep 0.05
echo "$sln" | pv -ls "$cln" > /dev/null
sleep 0.05
sln="$sln
$i"
sleep 0.05
printf "${tmpsum/\-}${tmpnam}\n" >> "$tmpfil"
echo -ne "$prev2line" > /dev/stderr
fi
done
sync
sleep 0.1
echo -ne "$next2line" > /dev/stderr
echo "-----"
if $verbose
then
sort -k2 "$tmpfil" | tee "$tmpfi2" | md5sum -c
echo "-----"
cat "$tmpfi2"
else
sort -k2 "$tmpfil"
fi
sleep 0.5
sync
rm -r "$tmpdir"
使用法
$ md5summer
Usage: /home/sudodus/bin/md5summer [-v] <pattern>
Example: /home/sudodus/bin/md5summer '*.iso' # notice the quotes
/home/sudodus/bin/md5summer -v '*.iso' # verbose
このディレクトリでテストしました
$ ls -1a
.
..
'filename with spaces'
md5summer
md5summer1
md5summer2
subdir
.ttt
zenity-info-message.png
隠しファイルを表示する通常の使用法とパターン
$ md5summer ".* *"
number of files = 6
total file size = 12649 B ~ 0 MiB
8,32KiB 0:00:00 [ 156MiB/s] [=============================> ] 67%
6,00 0:00:00 [ 133k/s] [====================================>] 100%
-----
184d0995cc8b6d8070f89f15caee35ce filename with spaces
28227139997996c7838f07cd4c630ffc md5summer
3383b86a0753e486215280f0baf94399 md5summer1
28227139997996c7838f07cd4c630ffc md5summer2
31cd03f64a466e680e9c22fef4bcf14b .ttt
670b8db45e57723b5f1b8a63399cdfa1 zenity-info-message.png
隠しファイルを表示する詳細な出力とパターン
$ md5summer -v ".* *"
number of files = 6
total file size = 12649 B ~ 0 MiB
8,32KiB 0:00:00 [ 184MiB/s] [=============================> ] 67%
6,00 0:00:00 [ 133k/s] [====================================>] 100%
-----
filename with spaces: OK
md5summer: OK
md5summer1: OK
md5summer2: OK
.ttt: OK
zenity-info-message.png: OK
-----
184d0995cc8b6d8070f89f15caee35ce filename with spaces
28227139997996c7838f07cd4c630ffc md5summer
3383b86a0753e486215280f0baf94399 md5summer1
28227139997996c7838f07cd4c630ffc md5summer2
31cd03f64a466e680e9c22fef4bcf14b .ttt
670b8db45e57723b5f1b8a63399cdfa1 zenity-info-message.png
ファイルへのリダイレクト、最初の画面出力
$ md5summer ".* *" > subdir/save
8,32KiB 0:00:00 [ 180MiB/s] [=============================> ] 67%
6,00 0:00:00 [ 162k/s] [====================================>] 100%
保存された出力
$ cat subdir/save
number of files = 6
total file size = 12649 B ~ 0 MiB
-----
184d0995cc8b6d8070f89f15caee35ce filename with spaces
28227139997996c7838f07cd4c630ffc md5summer
3383b86a0753e486215280f0baf94399 md5summer1
28227139997996c7838f07cd4c630ffc md5summer2
31cd03f64a466e680e9c22fef4bcf14b .ttt
670b8db45e57723b5f1b8a63399cdfa1 zenity-info-message.png
ISOファイルの確認
$ md5summer "*.iso"
number of files = 10
total file size = 7112491008 B ~ 6783 MiB
28,0MiB 0:00:00 [ 160MiB/s] [> ] 0%
10,0 0:00:00 [ 204k/s] [====================================>] 100%
-----
7a27fdd46a63ba4375896891826c1c88 debian-live-8.6.0-AMD64-lxde-desktop.iso
d70eec28cdbdee7f7aa95fb53b9bfdac debian-live-8.7.1-AMD64-standard.iso
382cfbe621ca446d12871b8945b50d20 debian-live-8.8.0-AMD64-standard.iso
44473dfe2ee1aad0f71506f1d5862457 debian-live-8.8.0-i386-standard.iso
f396b3532fa84059e7738c3c1827bada debian-live-9.3.0-AMD64-cinnamon.iso
8f6def28ae7cbefa0a6e59407c884466 debian-live-9.6.0-AMD64-cinnamon.iso
90b1815da0a5bf4ee4b00eec2b5d3587 debian-testing-AMD64-netinst_2017-07-28.iso
8f75074ab98e166b7469299d3e459ac6 mini-AMD64-2016-01-21-daily.iso
e580266fba58eb34b05bf6e13f51a047 mini-jessie-32.iso
646c109a9a16c0527ce1c7afa922e2ed mini-jessie-64.iso