출력이 매우 큰 파이프라인 명령

출력이 매우 큰 파이프라인 명령

tar디렉토리를 가져와 결과를 작성한 stdout다음 다음과 같이 압축기에 파이프하고 싶습니다 .

tar -cvf - /tmp/source-dir | lzip -o /media/my-usb/result.lz -

저는 여러 줄의 텍스트가 포함된 명령을 출력하기 위해 파이프를 사용해 왔습니다. 이제 매우 큰 출력(예: tar매우 느린 압축 명령이 뒤따름)이 포함된 (빠른) 명령을 파이프하면 어떻게 되는지 궁금합니다 . tar출력이 소비될 때까지 기다리 나요 lzip? 아니면 가능한 한 빨리 모든 것을 RAM에 출력합니까? 후자가 사실이라면 RAM이 적은 시스템에는 재앙이 될 것입니다.

답변1

데이터 생산자( tar)가 파이프에 너무 빨리 쓰려고 하여 소비자( lzip)가 모든 데이터를 읽을 시간이 없으면막힌쓰여진 내용을 lzip읽을 시간이 있을 때까지 . tar파이프와 관련된 작은 버퍼가 있지만 그 크기는 아마도 tar대부분의 아카이브보다 작을 것입니다. 파이프가 시스템 RAM을 채울 위험이 없습니다.

"차단"은 단순히 tar라이브러리 함수(또는 이에 상응하는 함수)가 호출될 때 데이터가 파이프 버퍼에 전달될 때까지 호출이 반환되지 않음을 의미하며, 동일한 버퍼에서 읽는 속도가 느린 경우 write()시간이 걸릴 수 있습니다 . lzip(실제로 더 빠르다고 가정할 때) 속도가 느려지고 잠이 많이 자는 곳과 비교 top하면 이를 볼 수 있습니다.tarlziptarlzip

그러므로 당신은아니요대량의 RAM을 채우려면 파이프를 사용하십시오. 이를 수행하려면(원하는 경우) pv큰 버퍼(여기서는 기가바이트)와 함께 중간에 다음과 같은 것을 사용할 수 있습니다.

tar -cvf - /tmp/source-dir | pv --buffer-size 1G | lzip -o /media/my-usb/result.lz -

tarpv차단될 때 마다 계속 차단됩니다. pv버퍼가 가득 차서 쓸 수 없을 때 차단됩니다 lzip.


반대의 경우도 비슷한 방식으로 작동합니다. 즉, 파이프의 왼쪽이 느리고 오른쪽이 빠른 경우 read()파이프에서 읽을 데이터가 있을 때까지 오른쪽의 소비자가 차단됩니다.

이(데이터 I/O)는 파이프에 참여하는 프로세스를 동기화하는 유일한 것입니다. 읽기 및 쓰기(다른 사람이 읽거나 쓰기를 기다리는 동안 가끔 차단됨)를 제외하고는 서로 독립적으로 실행됩니다.

답변2

암소 비슷한 일종의 영양아스팔트가지다--lzip옵션"lzip을 통해 아카이브 필터링”, 따라서 다음을 대신 사용할 수도 있습니다.

tar -cvf --lzip /media/my-usb/result.lz /tmp/source-dir

질문에 답하십시오. 귀하의 경우 시스템은 기본 시스템 버퍼 크기를 사용하여 파이프를 올바르게 관리합니다.

관련 정보