md5sum 在校验和前面加上 '\'

jsa*_*aji 22 coreutils hashsum checksum

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

$ md5sum /tmp/test\\test
\d41d8cd98f00b204e9800998ecf8427e  /tmp/test\\test
Run Code Online (Sandbox Code Playgroud)

每个其他实用程序也是如此。

Ste*_*itt 33

对于 Coreutils',这是记录在案md5sum

如果file包含反斜杠或换行符,则该行以反斜杠开头,文件名中的每个有问题的字符都用反斜杠转义,即使存在任意文件名,也使输出明确。

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

b2sum, sha1sum, 以及各种SHA-2 工具的行为方式与md5sum. sumcksum没有; sum仅用于提供向后兼容性(及其祖先不产生引述输出),并且cksum由POSIX指定,并且不允许这种类型的输出。

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

md5sum现在通过在行的开头使用 '\' 并用 '\n' 替换任何换行符,确保每个文件在标准输出上的状态为单行。这也影响sha1sumsha224sumsha256sumsha384sumsha512sum

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

  • 遗憾的是,像这样完全不直观的东西没有记录在`man` 页面中。(是的,我知道 GNU 想让每个人都阅读他们高度复杂的“信息”页面。) (30认同)
  • @msouth 行首的反斜杠作为一个标志,表明文件名中的反斜杠是转义符;否则你将不知道是将 `\n` 等处理为文字还是转义。 (3认同)
  • @msouth 如果它位于文件名的开头,您将无法知道它是标志还是真正以反斜杠开头的文件名... (3认同)
  • 文档中的短语“文件名中的每个有问题的字符都用反斜杠转义”是错误的;用 `\n` 替换换行符与用反斜杠转义换行符不同! (2认同)

Typ*_*eIA 17

Stephen Kitt 的回答涵盖了内容,我将尝试说明实施此更改的原因。首先,有人观察到包含换行符1的文件名可能导致输出不明确。例如,考虑这个输出:

d41d8cd98f00b204e9800998ecf8427e  foo
25af89c92254a806b2e93fffd8ac1814  bar
Run Code Online (Sandbox Code Playgroud)

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

764efa883dda1e11db47671c4a3bbd9e  foo\nbar
Run Code Online (Sandbox Code Playgroud)

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

764efa883dda1e11db47671c4a3bbd9e  foo\\nbar
Run Code Online (Sandbox Code Playgroud)

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


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

  • @Ruslan 重点是抗议 POSIX 允许此类 [antisocial](https://www.dwheeler.com/essays/fixing-unix-linux-filenames.html) 名称。允许此类字符可能会导致大量安全问题和代码膨胀,只是为了处理此类特殊情况。 (2认同)