比较校验和的快速脚本

比较校验和的快速脚本

我有一堆文件,需要验证它们的校验和。我有一个文本文件,如下所示:

校验<tab>和文件名<new line>

我想我可以用它作为练习来改进我的 shell 脚本。这就是我想出的方法,它成功了,我只是好奇是否有更好的方法。我意识到它不是很灵活(例如假设文件的格式和算法是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

作为Gohu指出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

这将外部实用程序调用的数量(在大多数 shell 中)减少到一次(SHA256 实用程序)。

在我的 OpenBSD 系统上生成 SHA256 校验和的 GNU coreutils 实用程序称为gsha256sum。我假设它的输出与shasum -a 256您的系统上的输出相同。

一些注意事项:

  • 我通常不会放在/目录名称的末尾。相反,我在使用变量时插入分隔符。这样我可以直接看到这$checkdir/checksum.txt是一个文件的路径,而${checkdir}checksum.txt(或类似的)则更加模糊。

  • 在尝试验证其校验和之前,我检查该文件是否确实存在。

  • 我没有使用 解析 SHA256 程序的输出awk,而是以与从校验和文件中读取校验和和文件名相同的方式读取它。我在一个上下文中这样做{ ...; }

  • 我正在治疗全部循环的输出作为“诊断消息”,并使用>&2after将其全部重定向到标准错误done

  • 我倾向于不在脚本中使用实用程序的绝对路径,除非有真正的理由这样做。printf例如,几乎总是 shell 内置实用程序,很少有理由/usr/bin/printf显式使用。

您很可能通过使用输入文件中的所有文件名来调用 SHA256 实用程序,然后比较该调用的校验和,从而对 SHA256 实用程序进行一次调用(或很少的调用),但代码可能会稍微复杂一些,而且工作量会很大。如果这是一次性的事情并且输入文件不是很大,那么就不值得。

相关内容