Liv*_*ivy 20 pipe shell-script
我想要tar
一个目录并将结果写入stdout
,然后将其通过管道传输到压缩程序,如下所示:
tar -cvf - /tmp/source-dir | lzip -o /media/my-usb/result.lz -
Run Code Online (Sandbox Code Playgroud)
我一直在使用管道来输出多行文本的命令。现在我想知道当我用管道输出一个(快速)命令时会发生什么,例如非常大的输出,tar
然后是一个非常慢的压缩命令?会tar
等待它的输出被消耗掉lzip
吗?或者它只是尽可能快地将所有内容输出到RAM?如果后者属实,那么在低 RAM 系统中将是一场灾难。
Kus*_*nda 45
当数据生产者 ( tar
) 试图太快地写入管道而消费者 ( lzip
) 没有时间读取所有数据时,它将阻塞,直到lzip
有时间读取tar
正在写入的内容。有一个与管道相关联的小缓冲区,但其大小可能小于大多数tar
档案的大小。不存在管道填满系统 RAM 的风险。
“阻塞”只是意味着当tar
调用write()
库函数(或等效函数)时,调用不会返回,直到数据被传递到管道缓冲区,如果lzip
从中读取速度很慢,这可能需要一些时间相同的缓冲区。与相比(假设实际上比 更快)相比,您应该能够top
在tar
会放慢速度和睡眠的地方看到这一点。lzip
tar
lzip
因此,您的管道不会填满大量 RAM。要做到这一点(如果你愿意的话),你可以pv
在中间使用类似的东西,有一些大的缓冲区(这里是一个千兆字节):
tar -cvf - /tmp/source-dir | pv --buffer-size 1G | lzip -o /media/my-usb/result.lz -
Run Code Online (Sandbox Code Playgroud)
tar
每当阻塞时,这仍然会pv
阻塞。 pv
当其缓冲区已满且无法写入时会阻塞lzip
。
相反的情况以类似的方式工作,即如果管道的左侧缓慢写入到快速右侧,则右侧的使用者将阻塞,read()
直到有数据要从管道读取。
这(数据 I/O)是同步参与管道的进程的唯一内容。除了读取和写入(偶尔会在等待其他人读取或写入时阻塞),它们会彼此独立运行。