我从 a 下载了多个文件回购还有更多文件。每个文件的 md5sum 信息存储在名为 .md5sum 的单个文件中MD5SUMS
。
为了检查文件完整性,我md5sum -c MD5SUMS
为文件中的所有文件生成了一个长输出MD5SUMS
,当找不到文件(我没有下载)时抱怨并在找到文件并且 md5sum 信息匹配时说“确定”。
md5sum: gencode.v27.tRNAs.gtf.gz: No such file or directory
gencode.v27.tRNAs.gtf.gz: FAILED open or read
md5sum: GRCh38.p10.genome.fa.gz: No such file or directory
GRCh38.p10.genome.fa.gz: FAILED open or read
GRCh38.primary_assembly.genome.fa.gz: OK
md5sum: _README.TXT: No such file or directory
_README.TXT: FAILED open or read
我已经将其通过管道grep
过滤掉“非正常”行,md5sum -c MD5SUMS | grep OK
但是我仍然得到了完整的输出我得到了很长的输出:带有“没有这样的文件或目录”的行表示不存在的文件和“正常”短语md5sum 匹配的文件以红色突出显示。
md5sum: gencode.v27.polyAs.gff3.gz: No such file or directory
md5sum: gencode.v27.polyAs.gtf.gz: No such file or directory
gencode.v27.primary_assembly.annotation.gff3.gz: OK
md5sum: gencode.v27.transcripts.fa.gz: No such file or directory
md5sum: gencode.v27.primary_assembly.annotation.gtf.gz: OK
但是,当我使用中间文件存储输出md5sum
然后存储grep
该文件时,我最终会得到包含短语“OK”的行,如预期的那样。
md5sum -c MD5SUMS > test
grep "OK" test
gencode.v27.primary_assembly.annotation.gff3.gz: OK
gencode.v27.primary_assembly.annotation.gtf.gz: OK
GRCh38.primary_assembly.genome.fa.gz: OK
我无法理解这个问题,你能帮我弄清楚管道出了什么问题还是预期的行为?
答案1
您会看到md5sum
因丢失文件而生成的错误消息。这些消息是在标准错误流上生成的,因为它永远是标准错误流输出流通过管道传递,错误消息grep
根本不会受到命令的影响。
要将它们重定向开以便您根本看不到它们,请使用
md5sum -c MD5SUMS 2>/dev/null | grep OK
如果要将错误保存到日志文件(例如,以便稍后检查丢失的文件),请替换/dev/null
为要写入错误的文件的名称。
位的解释2>/dev/null
:
一个命令在可能的两个单独的流上生成输出,标准输出流和标准错误流。它们始终分配给“文件描述符”1 和 2。
标准输出流是命令的“普通输出”所在的位置,这可能会通过管道传输到其他命令,就像在您的示例中通过管道传输到grep
.
标准错误流是“诊断消息”所在的位置(这通常意味着“错误”),这可以不是通过管道传输到另一个命令,通常直接进入终端。这就是为什么你的grep
命令似乎无法过滤掉错误消息;事实上,它甚至从未见过它们。
通过2>
将标准错误流重定向到其他地方,这样其上生成的任何内容都不会最终出现在终端上。
重定向标准输出流的等效项是1>
,它可以缩短为>
。
该/dev/null
文件很特殊。写入其中的所有内容都会完全消失。
在命令之后使用2>/dev/null
意味着所有错误消息都被重定向到/dev/null
而不是终端,因此被丢弃。