md5sum在校验和前加上“ \”


22

查找名称中带有“ \”的文件的校验和时,为什么md5sum在校验和前加“ \”?

$ md5sum /tmp/test\\test
\d41d8cd98f00b204e9800998ecf8427e  /tmp/test\\test

对于其他所有实用程序,请注意相同的内容。


仅供参考,GNU coreutils中的其他*sum实用程序(与md5sum,例如e,g sha1sum等相同)。
Kusalananda

我没有看到这种行为,该实用程序的版本是什么:md5sum --version
Kiwy

@Kusalananda这可能是特定于coreutils版本的;在CentOS 7 cksum上没有;例如% cksum test\\test 3915528286 4 test\test
Stephen Harris

@StephenHarris这可能是因为cksumPOSIX实用程序及其规格。不允许。
库萨兰达

Answers:


33

这是记录在案,为Coreutils的md5sum

如果文件包含反斜杠或换行符,则该行以反斜杠开始,并且文件名中的每个有问题的字符都以反斜杠转义,即使在存在任意文件名的情况下,输出也清晰无误。

file是文件名,而不是文件的内容)。

b2sumsha1sum和,各种SHA-2工具的行为与相同md5sumsum而且cksum不要 sum仅用于提供向后兼容性(及其祖先不产生引述输出),并且cksum由POSIX指定,并且不允许这种类型的输出。

此行为于2015年11月引入,并在8.25版(2016年1月)中发布,具有以下NEWS条目:

md5sum现在,通过在行的开头使用“ \”,并将所有换行符替换为“ \ n”,确保每个文件在标准输出中的状态为一行。这也影响sha1sumsha224sumsha256sumsha384sumsha512sum

行首的反斜杠用作标志:仅当行以反斜杠开头时才处理文件名中的转义。(转义不能成为默认行为:它将破坏使用包含\\\n存储的文件名的较旧版本的Coreutils生成的总和。)


30
可惜的是,man页面中没有记录像这样完全不直观的内容。(是的,我知道GNU希望每个人都阅读它们高度info
混乱的

3
@msouth行首的反斜杠用作标志,指示文件名中的反斜杠已转义;否则,您将不知道是将其\n作为文字还是转义进行处理。
斯蒂芬·基特

3
@msouth,如果它位于文件名的开头,则您无法知道它是标志,还是真正以反斜杠开头的文件名……
Stephen Kitt

1
@StephenKitt我不认为领导\可以消除歧义。如果将输出记录为总是转义反斜杠和换行符,则不会有任何歧义。在那里,因此在不必要的情况下不必进行转义。您当然可以辩论这是否值得(我个人认为不值得,但我不是coreutils贡献者)。
TypeIA

1
文档中的短语“文件名中的每个有问题的字符都用反斜杠转义”是错误的;用替换\n换行符与用反斜杠转义换行符不同!
ruakh

17

斯蒂芬·基特(Stephen Kitt)的答案涵盖了什么,我将尝试说明实施此更改的原因。首先,有人发现包含换行符1的文件名可能导致输出不明确。例如,考虑以下输出:

d41d8cd98f00b204e9800998ecf8427e  foo
25af89c92254a806b2e93fffd8ac1814  bar

这是否意味着有两个文件foobar,或者只有一个文件名是"foo\n25af89c92254a806b2e93fffd8ac1814 bar"?当然,后一种可能性极不可能,但有可能。为了解决歧义,开发人员选择使用反斜杠(\)换行。然后,输出变得可区分。但是,还有另一个歧义:

764efa883dda1e11db47671c4a3bbd9e  foo\nbar

此文件的名称是否包含换行符或反斜杠后跟一个n?为了解决这个问题,我们也需要转义反斜杠,以便后一种情况变为:

764efa883dda1e11db47671c4a3bbd9e  foo\\nbar

最后,他们选择在包含此类转义的每条输出行之前加上a,\\以使解析器易于检测是否已完成转义。大概这样做是为了允许解析器处理转义版本md5sum和非转义版本(非GNU)的输出。该标志还意味着不需要时不必进行“代价高昂的”转义。您可以看到一个md5sum.c本身进行解析的示例(链接版本中的第382行)。


1通过换行我的意思的字符\n其有时也特别被称为换行LF ; 见md5sum.c


1
当然,理智的行为是完全禁止每个包含换行符的文件。只是拒绝处理它们。
管道

1
@pipe这是疯狂的行为。POSIX确实允许使用此类文件名,并且故意拒绝使用合法文件的实用程序很糟糕,必须将其杀死。
罗斯兰

2
@Ruslan重点是抗议POSIX允许使用这种反社会名称。允许使用此类字符可能会导致大量的安全问题,并且仅是为了处理此类特殊情况而导致代码膨胀。
管道

@pipe虽然文件名中的LF确实是反社会的,但您链接中提到的其他内容则更具争议性,例如空格,非拉丁字母等
。– Ruslan,

工程师经典的过度设计。教训(再次):不允许工程师提出要求。他们会发现最模糊,最复杂的案例,并将其提升为主导案例,并使所有人感到困惑。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.