为什么 du -sk 无法报告 fifo 的大小?

为什么 du -sk 无法报告 fifo 的大小?

bash 中有一个概念叫进程替换。你可以运行一个命令,并将输出作为文件使用。

例如

$ cat -n <(seq 3|tac)
     1  3
     2  2
     3  1

我很好奇为什么以下操作会失败;

$ du -sk <(xzcat /var/log/mpd/scribble.log.xz )
0   /dev/fd/63

同样地,我们有这个

$ file <(seq 1 2)
/dev/fd/63: broken symbolic link to pipe:[32560687]

该文件不为空。

$ xzcat /var/log/mpd/scribble.log.xz  | wc -c 
16877047

>/dev/null  pv  <(xzcat /var/log/mpd/scribble.log.xz ) 
16.1MiB 0:00:00 [ 232MiB/s] [  <=>                   ]

作为一个附加问题,您是否知道在 bash 中将 fifo 在短时间内伪装成常规文件的技巧?

答案1

常规文件由三个主要部分组成:

  1. 名称(硬链接)
  2. Inode(系统信息)
  3. 主体(数据)

管道(无论是命名管道还是匿名管道、持久管道还是临时管道)都没有主体。因此,与常规文件不同,它们的大小始终为零。它们只有内存缓冲区。这就是匿名命名管道 /dev/fd/63 的长度为零的原因。您可以在 <(...) 运算符内使用任何其他命令,结果相同,例如

du -sk <(cat somefile)

您可以使用 mkfifo 命令创建命名管道,以查看即使完全填满其缓冲区,其大小也始终等于零。实际上,命名管道(以及任何其他管道)的文件大小没有实际意义,并且设置为零以与其他文件列表保持一致。

相关内容