md5sum コマンドが完了するまで待ちます。

md5sum コマンドが完了するまで待ちます。
#!/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つずつ実行することを意味し、これは非常に非効率的です。zargsmd5summd5sum-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 ... md5sum2番目のパスに渡す前にコマンド出力からファイル名を削除できますmd5sum

#!/bin/bash

zenity --info \
--title="Calculated checksum" \
--text="$(find /path-to-directory -type f -exec md5sum {} \; | cut -d ' ' -f1 | sort -k 2 | md5sum)"

関連情報