只保留管道的最后 N 个字节?

只保留管道的最后 N 个字节?

我正在将数据从套接字传输到文件。如果我需要保存所有数据,这很简单:

$ nc -l 5001 > file.bin

如果我只想保存第一个n字节,那就是足够容易还有:

$ nc -l 5001 | pv -Ss 2M > file.bin

有没有一种方法可以将数据通过管道传输到具有固定最大大小的文件,这样当新数据到达时,它会像队列一样取代文件中的旧数据?如果存在这样的东西,也许可以使用固定大小的命名管道。

理想情况下,这将连续运行,不需要保存所有文件,然后对其进行切割。换句话说,我不想tail在保存整个文件后简单地运行。

答案1

对于 n = 2M,使用:

nc -l 5001 | tail -c 2M > file.bin

或者使用这个:

nc -l 5001 | tail -c 2097152 > file.bin

答案2

那么,您希望能够随时查看最后 N 个字节,而不必存储更多字节,我的理解是否正确?

如果您想要真正实时地(如逐字节),您可能需要一些专用软件。通常,人们会将最新数据存储在环形缓冲区中,但您可能找不到可以从文件中读取这样排列的数据的软件。另一种选择是以正常方式将所有数据写入文件,并定期告诉操作系统丢弃不再需要的早期数据。 (我想我之前看到过一条评论暗示这一点,但也许它被删除了。)

您可能可以使用 Perl 脚本来做到这一点fallocate进行丢弃。

如果您不需要最新的数据,快速而肮脏的 shell 解决方案会将固定块存储在文件中,并在每个块之间将文件重命名为另一个名称。最新的完整块将始终在第二个文件中可用。

例如

i=0
while true; do echo $i; sleep .1; i=$((i+1)); done |
    while true; do
        head -10 > out1
        mv out1 out2
    done

第一个循环产生一些测试输出,而第二个循环读取 10 行的块,以便最后一个完整块位于 中out2,最后一个部分块位于 中out1head根据需要更改参数。

请注意,对于这样的小块,输出缓冲headout1始终显示为空。stdbuf -o0 head ...如果这是一个问题,请使用它。

相关内容