You know how whenever you download a file you should really compare the hash of the download to the one provided on the website? This makes absolute sense, but it's a pain to do it letter for letter, digit for digit. So, I wrote this little script to take care of the job. Any comments are welcome.

#!/bin/bash

error_exit()
{
echo "$1" 1>&2 exit 1 } usage="usage: hash_checker downloaded_file hash_provided -a algorithm" downloaded_file= hash_given= hash_calc= algo="sha256" # check if file and hash were provided if [$# -lt 2 ]; then
error_exit "$usage" fi # parsing the provided hash and file downloaded_file="$1"
hash_given="$2" # parsing the algorithm, if provided if [ "$3" != "" ]; then
if [ "$3" = "-a" ]; then algo="$4"
else
error_exit "$usage" fi fi # check if input is a valid file if [ ! -f "$downloaded_file" ]; then
error_exit "Invalid file! Aborting."
fi

# calculate the hash for the file
hash_calc="$($algo'sum' $downloaded_file)" hash_array=($hash_calc)
hash_calc=${hash_array[0]} # compare the calculated hash to the provided one if [ "$hash_calc" = "$hash_given" ]; then echo "The hashes match. File seems to be valid." else echo "The hashes do not match. File does not seem to be valid." fi  • Why not just use the -c option to sha1sum or md5sum to do the comparison? – Toby Speight Sep 13 '18 at 7:16 • Didn't know that was an option. Kinda expected something like this must exist, thanks. – iuvbio Sep 13 '18 at 7:25 1 Answer Notes: • I'd use getopts for arg parsing -- lots of examples on stackoverflow about how to use it. • always quote your variables • you should validate the algorithm: sum_exe="${algo}sum"
if ! type -P "$sum_exe" >/dev/null; then error_exit "'$algo' is an unknown checksum algorithm"
fi

• have the checksum program read from stdin, then you don't have to do your incorrect unsafe word parsing since the program will not print a filename

hash_calc=$( "$sum_exe" < "$downloaded_file" )  As the above doesn't work, let's use read from a process substitution read -r hash_calc _ < <("$sum_exe" < "\$downloaded_file")

• Thanks for your notes. Reading from stdin the filename is not printed, but  - is appended to the hash, and thus the test fails. Is there a way around that other than more word parsing? – iuvbio Sep 12 '18 at 20:21
• I've updated my answer – glenn jackman Sep 12 '18 at 20:42