![当计算的校验和不匹配时如何显示不正确的校验和](https://linux22.com/image/13789/%E5%BD%93%E8%AE%A1%E7%AE%97%E7%9A%84%E6%A0%A1%E9%AA%8C%E5%92%8C%E4%B8%8D%E5%8C%B9%E9%85%8D%E6%97%B6%E5%A6%82%E4%BD%95%E6%98%BE%E7%A4%BA%E4%B8%8D%E6%AD%A3%E7%A1%AE%E7%9A%84%E6%A0%A1%E9%AA%8C%E5%92%8C.png)
假设我尝试使用以下方法验证文件的校验和:
echo '760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3 emacs-26.1.tar.gz' | \
sha256sum --check
如果文件损坏且校验和错误,sha256sum
将显示以下消息:
emacs-26.1.tar.gz: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
我想知道文件的实际校验和(即导致此错误消息的错误校验和)。我有什么选择?如果可能的话,我不想计算校验和两次(一次是为了看到“FAILED”消息,第二次是为了看到不正确的校验和)。
(操作系统:Ubuntu 20.04)
答案1
查看 GNUcoreutils
实现的源代码,perl
one ( shasum
) 或 ast-open one ( sum
),它们都不能被告知以验证模式输出计算的和。
有了perl
它,修改它就很容易了:
--- shasum.orig 2021-03-27 08:01:06.927965948 +0000
+++ shasum 2021-03-27 08:02:33.336241906 +0000
@@ -295,7 +295,7 @@
$isOK = 1;
$num_OK++;
}
- else { $rsp .= "FAILED\n"; $err = 1; $match_errs++ }
+ else { $rsp .= "FAILED (expected $sum, got $digest)\n"; $err = 1; $match_errs++ }
print $rsp unless ($status || ($quiet && $isOK));
}
close(FH);
进而:
$ echo '760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3 a' | ./shasum -a 256 -c
a: FAILED (expected 760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3, got 3a1edb0672af06bc4712da1fcc00a09326e550d3f503ca41bf59d259f46afdc9)
答案2
下面的 shell 脚本通过将计算出的校验和保存到变量中来解决该问题。然后将保存的校验和与预期的校验和进行比较。如果需要,保存的校验和可以显示在错误消息中。
#!/bin/sh
file='emacs-26.1.tar.gz'
expected='760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3'
actual="$(sha256sum "$file" | awk '{print $1}')"
if [ "$actual" = "$expected" ]; then
echo "${file}: OK"
else
echo "${file}: FAILED"
echo "Expected: $expected" >&2
echo "Observed: $actual" >&2
exit 1
fi
模仿echo "${file}: OK
的输出格式sha256sum --check
,并且使用Expected: ...
和Observed: ...
来代替sha256sum --check
的sha256sum: WARNING: 1 computed checksum did NOT match
错误消息。
答案3
也许像这样的 bash 函数可以工作?
function check {
file="$1"
expected="$2"
echo "$expected $file" | sha256sum --check
result=$?
if [ $result -ne 0 ]; then
printf "Expected: %s\n" "$expected"
printf "Observed: %s\n" $(sha256sum "$file" | awk '{print $1}')
fi
}
这是一个演示:
#!/bin/bash
function check {
...
}
file="emacs-26.1.tar.gz"
expected=760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3
if [ ! -e "$file" ]; then
touch "$file"
fi
echo "This is what a mismatched file looks like"
check $file $expected
printf "\n--------------------------------------\n"
echo "This is what a matching file looks like"
expected=$(sha256sum "$file" | awk '{print $1}')
check $file $expected
输出:
This is what a mismatched file looks like
emacs-26.1.tar.gz: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Expected: 760382d5e8cdc5d0d079e8f754bce1136fbe1473be24bb885669b0e38fc56aa3
Observed: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
--------------------------------------
This is what a matching file looks like
emacs-26.1.tar.gz: OK