ファイルが多すぎるため、チェックサムを確認する必要があります。次のテキストファイルがあります。
チェックサム<tab>
ファイル名<new line>
私はこれをシェルスクリプトを改善するための練習として使用できると思いました。これが私が思いついたもので、効果がありました。より良い方法があるかどうか疑問に思いました。柔軟性があまりないことがわかります(例:ファイル形式とアルゴリズムが256であると仮定)。しかし、避けようとしていますcat
... echo
:)
ありがとうございます!
#!/bin/sh
workingDir="/path/to/directory/"
textFile="checksums.txt"
filePath="$workingDir$textFile"
while read a b; do
shasumOutput=$(/usr/bin/shasum -a 256 "$workingDir$b" | /usr/bin/awk '{ print $1 }')
if [ "$a" = "$shasumOutput" ]; then
/usr/bin/printf "$b checksum matches: "$a", "$shasumOutput"\n"
else
/usr/bin/printf "$b checksum doesn't match: "$a", "$shasumOutput"\n"
fi
done < "$filePath"
答え1
〜のように甲府が指摘したshasum
あなたのコメントには、そのフラグに対してすでに完了している確認をコピーしています-c
。
入力はshasum -c
結果コンテンツでなければなりませんshasum
。
これを無視してください...
あなたのスクリプトはよさそうですが、いくつかについて言及することができます。
この行は、たとえば代わりprintf
に で で書くことをお勧めします。printf 'format string' "$var1" "$var2" "etc."
/usr/bin/printf "$b checksum matches: "$a", "$shasumOutput"\n"
使用
printf '%s checksum matches: %s, %s\n' "$b" "$a" $shasumOutput"
使用のポイントprintf
は、静的型文字列と型文字列テンプレートに入るいくつかの変数データがあることです。
また、$( shasum ... )
外部ユーティリティへの呼び出しの数を避けて減らすために、次のことを行います。
#!/bin/sh
checkdir='/some/path'
checkfile="$checkdir/checksums.txt"
while read -r checksum filename; do
if [ ! -f "$checkdir/$filename" ]; then
printf 'Not found: %s\n' "$filename"
continue
fi
gsha256sum "$checkdir/$filename" | {
read -r realsum name
if [ "$realsum" != "$checksum" ]; then
printf 'Mismatch for "%s":\n\t%s != %s\n' \
"$filename" "$checksum" "$realsum"
else
printf '%s OK\n' "$filename"
fi
}
done <"$checkfile" >&2
これにより、外部ユーティリティの呼び出し(ほとんどのシェルで)の数が1回(SHA256ユーティリティ)に減少します。
私のOpenBSDシステムでSHA256チェックサムを生成するGNU coreutilsユーティリティはgsha256sum
。私はその出力がshasum -a 256
あなたのシステムと同じであると仮定します。
いくつかの注意:
/
私は通常ディレクトリ名の末尾に入れません。代わりに変数を使用するときに区切り文字を挿入します。これにより、これが$checkdir/checksum.txt
ファイルへのパスであることを直接見ることができますが${checkdir}checksum.txt
(または同様に)もっと曖昧です。チェックサムを確認する前に、ファイルが実際に存在することを確認してください。
SHA256を解析するプログラムの出力を使用する代わりに、チェックサムファイル
awk
からチェックサムとファイル名を読み取るのと同じ方法で読み込みます。私は状況に応じてこれを行います{ ...; }
。私は治療中です。みんなループの出力は「診断メッセージ」として機能し、
>&2
その後すべてのメッセージを標準エラーにリダイレクトするために使用されますdone
。私は実際の理由がない限り、スクリプトでユーティリティへの絶対パスを使用しない傾向があります。たとえば、ユーティリティはほとんど常にシェルに組み込まれており、それを明示的に使用する
printf
理由はほとんどありません。/usr/bin/printf
入力ファイル内のすべてのファイル名を使用してSHA256ユーティリティを呼び出してから、その呼び出しのチェックサムを比較してSHA256ユーティリティを1回(または非常に少ない呼び出し)呼び出すことができますが、コードはおそらくもう少し複雑です。作業量が途方もないだろう。これがワンタイムであり、入力ファイルがそれほど大きくない場合はそれほど価値がありません。