perl shasum vs bash shasum

时间:2014-09-26 20:28:52

标签: bash perl sha

以下bash和Perl脚本神秘地给出了不同的结果。为什么呢?

#!/bin/bash                                                                       
hash=`echo -n 'abcd' | /usr/bin/shasum -a 256`;
echo $hash;

#!/usr/bin/perl                                                                   
$hash = `echo -n 'abcd' | /usr/bin/shasum -a 256`;
print "$hash";

bash脚本:

$ ./tst.sh
88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589 -

Perl脚本:

$ ./tst.pl
61799467ee1ab1f607764ab36c061f09cfac2f9c554e13f4c7442e66cbab9403  -
哎呀?

2 个答案:

答案 0 :(得分:18)

摘要:在您的Perl脚本中,-n被视为要包含在echo输出中的参数,而不是用于禁止换行的标志。 (试试

$hash = `echo -n 'abcd'`;

确认)。请改用printf


Perl使用/bin/sh来执行后台抽动中的代码。即使/bin/shbash的链接,当通过它调用时,它的行为也会有所不同。在POSIX模式下,

echo -n 'abcd'

将输出

-n abcd

也就是说,-n选项不会被识别为禁止换行的标志,但会被视为要打印的常规参数。在每个脚本中将echo -n替换为printf,您应该从每个脚本获得相同的SHA哈希值。

(更新:bash 3.2,当调用为sh时,会显示此行为。bash的较新版本似乎会在调用{-n时将其作为标记继续处理{1}}。)


更好的是,不要在Perl做你可以做的事情。

sh

对于好奇的,这里有关于use Digest::SHA; $hash = Digest::SHA::sha256('abcd'); 的POSIX规范has to say。我不知道如何制作XSI一致性; echo bash需要echo选项专门处理转义字符,但几乎每个shell- 除了旧版-e,然后只有在特殊情况下 - 将bash视为标志,而不是字符串。哦,好吧。

-n

答案 1 :(得分:6)

如果你这样做:

printf "%s" 'abcd' | /usr/bin/shasum -a 256

你得到88d ... 589哈希。如果你这样做:

printf "%s\n" '-n abcd' | /usr/bin/shasum -a 256

你得到617 ... 403哈希。

因此,我推断Perl以某种方式运行不同的echo命令,可能是/bin/echo/usr/bin/echo而不是bash内置echo,或者可能是/bin/sh的内置回声(可能是dash而不是bash),而另一个echo无法识别-n选项作为选项并输出不同的数据。

我不确定它找到了哪个echo;在我的运行Ubuntu 14.04 LTE衍生产品的计算机上,bashdashsh(已关联到bash),kshcshtcsh所有人都以同样的方式对待echo -n abcd。但在某个地方,我认为沿着这些路线发生了一些事情;哈希校验和是相同的强烈指向它。 (也许你有一个与bash相关联的3.2 sh;请参阅评论中的注释。)