ダウンロードしたファイルのハッシュ値を確認するスクリプト

Bash

はじめに

他の方のエントリで、ダウンロードしたファイルのハッシュ値のチェック処理をシェルスクリプトで書かれていたので勉強がてら読んでみました。
自分だったらこう書くかな?という違いが合ったので、良い勉強になりました。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ bash -version | head -n 1
GNU bash, バージョン 5.0.16(1)-release (x86_64-apple-darwin18.7.0)

参考にしたスクリプト

自分だったらこう書くかな?という部分を書き換えてました。

ファイル名は check-hash

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o noclobber

usage() {
  progname=$(basename "$0")
  cat <<EOM
Usage:
  ${progname} hash file
EOM
  exit 0
}

normalize_hash() {
  sed 's/ //g' | tr '[:lower:]' '[:upper:]'
}

detect_algo() {
  declare hash="${1}"
  if [[ ${hash} =~ [^0-9A-F] ]]; then
    echo "error: hash contains invalid character: ${hash}" >&2
    return 1
  fi
  case "${#hash}" in
    32) echo "MD5 md5sum" ;;
    40) echo "SHA1 sha1sum" ;;
    56) echo "SHA224 sha224sum" ;;
    64) echo "SHA256 sha256sum" ;;
    96) echo "SHA384 sha384sum" ;;
    128) echo "SHA512 sha512sum" ;;
    *)
      echo "error: could not detect hash algorithm: ${hash}" >&2
      return 1
      ;;
  esac
}

main() {
  [[ $# -ne 2 ]] && usage

  declare hash=$(echo ${1} | normalize_hash)
  declare file=$([[ ${2} != - ]] && echo "${2}" || echo /dev/stdin)

  read algo cmd < <(detect_algo "${hash}" || exit $?)
  declare hash_from_file=$("${cmd}" <"${file}" | awk '{ print $1 }' | normalize_hash)

  if [[ ${hash} != "${hash_from_file}" ]]; then
    echo "[Error] The hashes are different! (hash: ${hash}, file: ${hash_from_file}, algo: ${algo})" >&2
    return 1
  else
    echo "[Success] The hashes are same (algo: ${algo})"
    return 0
  fi
}

main "$@"

ひとこと

人のソースコードは、新しい書き方がたくさん見つかって面白い。

Bash