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
常规文件由三个主要部分组成:
- 名称(硬链接)
- Inode(系统信息)
- 主体(数据)
管道(无论是命名管道还是匿名管道、持久管道还是临时管道)都没有主体。因此,与常规文件不同,它们的大小始终为零。它们只有内存缓冲区。这就是匿名命名管道 /dev/fd/63 的长度为零的原因。您可以在 <(...) 运算符内使用任何其他命令,结果相同,例如
du -sk <(cat somefile)
您可以使用 mkfifo 命令创建命名管道,以查看即使完全填满其缓冲区,其大小也始终等于零。实际上,命名管道(以及任何其他管道)的文件大小没有实际意义,并且设置为零以与其他文件列表保持一致。