#!/bin/bash
cd /path-to-directory
md5=$(find . -type f -exec md5sum {} \; | sort -k 2 | md5sum)
zenity --info \
--title= "Calculated checksum" \
--text= "$md5"
ディレクトリの再帰チェックサム計算プロセスには時間がかかります。 Bashスクリプトは、プロセスが完了するのを待たずに、計算されたチェックサムを表示するダイアログボックスである次のコマンドに移動します。したがって、ダイアログボックスに無効なチェックサムが表示されます。
チェックサムの計算が完了するのを待つようにスクリプトに指示するオプションはありますか?また、チェックサム計算の進行状況をzenityなどの進行状況バーにパイプするオプションはありますか?
答え1
書かれたとおり待ちます。振動する進行状況バーの場合:
#! /bin/sh -
export LC_ALL=C
cd /path/to/dir || exit
{
md5=$(
find . -type f -print0 |
sort -z |
xargs -r0 md5sum |
md5sum
)
exec >&-
zenity --info \
--title="Checksum" \
--text="$md5"
} | zenity --progress \
--auto-close \
--auto-kill \
--pulsate \
--title="${0##*/}" \
--text="Computing checksum"
実際の進行状況バーでは、処理するファイルの数を事前に知っておく必要があります。
そしてzsh
:
#! /bin/zsh -
export LC_ALL=C
autoload zargs
cd /path/to/dir || exit
{
files=(.//**/*(ND.))
} > >(
zenity --progress \
--auto-close \
--auto-kill \
--pulsate \
--title=$0:t \
--text="Finding files"
)
md5=(
$(
zargs $files -- md5sum \
> >(
awk -v total=$#files '/\/\// {print ++n * 100 / total}' | {
zenity --progress \
--auto-close \
--title=$0:t \
--text="Computing checksum" || kill -s PIPE $$
}) \
| md5sum
)
)
zenity --info \
--title=$0:t \
--text="MD5 sum: $md5[1]"
ロケールの外部ではC
、少なくとも GNU システムではファイル名の順序は定義されません。一部の文字は同じように並べ替えられ、上記のようにファイル名が有効なテキストで構成されるという保証はありませんLC_ALL=C
。
Cロケールの順序も非常に単純であり(バイト値に基づいて)、システムとバージョン全体で一貫しています。
これは、エラーメッセージ(存在する場合)がユーザーの言語ではなく英語で表示されることを意味します(ただし、ローカライズされてComputing checksum
いないFinding files
ので大丈夫です)。
アプローチに対するいくつかのその他の改善点は次のとおりです。
- それぞれ複数のファイルを転送する呼び出しの数を最小限に抑えるには、または
-exec md5sum {} +
(-print0 | xargs -r0 md5sum
または同等のもの)を使用します。これは、各ファイルに対して1つずつ実行することを意味し、これは非常に非効率的です。zargs
md5sum
md5sum
-exec md5sum {} \;
md5sum
- ファイルリストをに渡す前にソートします
md5sum
。通常、sort -k2
ファイル名に改行文字を含めることができるため、この方法は機能しません。通常、ファイルパスを行単位で処理するのは間違っています。ファイル数を確実に計算.//
できるように、zshメソッドでプレフィックスを使用していることがわかりますawk
。一部の実装では、NULで区切られたレコードオプションmd5sum
も提供されます。-z
答え2
このコードは待機find
し、md5sum
コマンドが完了します。&
バックグラウンドでコマンドを送信する必要がない限り、これは通常の動作です。
しかし、あなたのzenityコマンドフォーマットが間違っています=
。したがって、空のzenityウィンドウが表示されるようです。これがまさに待たないと思う理由です。もう一度やり直してもスペースを削除してください。
#!/bin/bash
cd /path-to-directory
md5=$(find . -type f -exec md5sum {} \; | sort -k 2 | md5sum)
zenity --info \
--title="Calculated checksum" \
--text="$md5"
これにより、必要性を避け、cd
より簡潔にすることができます。
#!/bin/bash
zenity --info \
--title="Calculated checksum" \
--text="$(find /path-to-directory -type f -exec md5sum {} \; | sort -k 2 | md5sum)"
ディレクトリの親パスが何であれ、常に同じ結果を返す必要がある場合は、それを使用してfind ... md5sum
2番目のパスに渡す前にコマンド出力からファイル名を削除できますmd5sum
。
#!/bin/bash
zenity --info \
--title="Calculated checksum" \
--text="$(find /path-to-directory -type f -exec md5sum {} \; | cut -d ' ' -f1 | sort -k 2 | md5sum)"