【问题标题】:Linux bash: Compare hash strings without setting variablesLinux bash:比较哈希字符串而不设置变量
【发布时间】:2018-09-12 08:47:00
【问题描述】:

我想要一个简单的 bash 命令来比较两个输出是否相同的哈希值。这是我尝试过的:

md5sum file1 | awk '{print $1}' # outputs hash value without filename

md5sum file1 > md5sum file2 # no output even though files/hashes differ

到目前为止,我已经尝试了以下变体,但没有成功:

[ md5sum states.txt | awk '{print $1}' == md5sum states_copy.txt | awk '{print $1}' ]

[ (md5sum states.txt | awk '{print $1}') == (md5sum states_copy.txt | awk '{print $1}') ]

我对脚本或多行 bash 解决方案或使用 shasum 持开放态度,但我是 Linux 和 bash 的新手,因此尽量保持简单。

我正在运行 Ubuntu 18.04。

【问题讨论】:

  • 只是想知道,但你为什么不使用if diff -q $file1 $file2 &>/dev/null; then do_your_stuff; fi 甚至更好的if cmp --silent $file1 $file2; then do_your_stuff; fi
  • @kvantour,我是 bash 新手,您的建议中有很多我不太了解的地方。从语法来看,我是否正确地将您的建议视为脚本,将$file1 等视为从命令行传入的变量?我尝试使用硬编码的文件名在命令行上运行您的第一个建议,然后使用echo $? 打印输出,但没有找到我预期的结果。你能详细说明我想在do_your_stuff 线上做什么吗?我可以在此处放置echo ... 以打印出差异比较的结果,如果可以,我将如何捕获该结果?
  • 您最初的问题是比较两个动态计算的 md5sum。所以你没有将它们存储在任何变量或任何东西中。这意味着您实际上是在尝试确定两个文件是否相同。命令cmpdiff 正是这样做的。所以你可以检查这些命令的返回码。 cmp --silent file1 file2diff -q file1 file2 &> /dev/null

标签: linux bash awk md5sum sha1sum


【解决方案1】:
[ "$(<states.txt md5sum)" = "$(<states_copy.txt md5sum)" ]
  1. 使用$(...)获取命令输出
  2. 记得在" 内附上$(...)
  3. Bash 测试支持单个 = 用于字符串比较,而不是双 ==
  4. 使用标准输入和&lt; 重定向将文件重定向到 md5sum。

【讨论】:

  • 赞赏输入重定向→摆脱特定文件名
  • @Kamil,我试过你的代码:$ [ "$(&lt;states.txt md5sum)" = "$(&lt;states_copy.txt md5sum)" ] 但它没有产生任何输出。然而,单独地,这些字符串确实返回了它们不同的哈希值:$ "$(&lt;states.txt md5sum)"8d7dd71ff51614e69339b03bd1cb86ac -: command not found$ "$(&lt;states_copy.txt md5sum)"2914e54cdea0fecac5cdf547628bfc26 -: command not found
  • 此代码集将退出状态作为输出。如果您想要“输出”,请尝试[ "$(&lt;states.txt md5sum)" = "$(&lt;states_copy.txt md5sum)" ]; echo $?。不要在它前面加上$
  • 另外,我试图了解 lt 符号 before 文件名 &lt;states.txt md5su 的使用,以将文件重定向到 md5sum。这和在文件名states.txt &gt; md5sum之后使用gt一样吗?
  • 不是lt,而是&lt;&lt; 将文件重定向到进程标准输入。 &gt; 将进程标准输出重定向到文件。 &gt;&gt; 将进程的标准输出附加到文件中。 md5sum &lt;states.txt&lt;states.txt md5sum 相同,与cat states.txt | md5sum 相同。见manual
【解决方案2】:

有很多方法可以做到,既然你用过awk,你可以试试:

md5sum f1 f2|awk '{a[$1]}END{print NR==length(a)}'

如果两个哈希值相同,则输出0,否则输出1。你可以向md5sum添加更多文件:

md5sum f1 f2 f3...fn|awk '{a[$1]}END{print NR==length(a)}'

【讨论】:

  • 最好使用exit 而不是print 这样它可以在if 语句中使用。
  • 您应该提到并非所有 awks 都支持length(array)(它不是 POSIX 的一部分)。
  • @Kent,当我运行以下命令时:$ md5sum states6.txt states_copy.txt | awk '{a[$1]}END{print NR==length(a)}' 我得到以下错误作为输出:awk: line 1: illegal reference to array a。我使用的是纯 Linux 系统 Ubuntu 18.04,如果这有什么不同的话。
  • @KarlBaker 正如 Ed 所说,length() 是 gnu 扩展。请检查您的 awk 具有哪个版本。不要使用ubuntu,我不能说。如果您使用的是 gawk,则该行应该可以工作。
  • 谢谢,@Kent!我安装了 gawk 并用 gawk 运行它,它工作正常。
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 2020-04-05
  • 2018-09-23
  • 2015-03-07
  • 2021-03-26
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多