[unix] 파이프 라인에서 무한한 양의 데이터를 버퍼링하는 유틸리티?

읽기 및 쓰기 속도를 분리하기 위해 파이프 라인에 연결할 수있는 유틸리티가 있습니까?

$ producer | buf | consumer

기본적 buf으로 가능한 빨리 입력을 읽고 메모리에 저장하여 최대한 빨리 실행 consumer하는 동안 달콤한 시간이 걸릴 수 있는 유틸리티 를 원합니다 producer.



답변

pv(파이프 뷰어) 유틸리티는이합니다 (로 할 수있는 -B보고서를 진행 제공을 포함하여 더 많은 옵션)합니다.


답변

당신은 사용할 수 있습니다 dd:

producer | dd obs=64K | consumer

모든 유닉스에서 사용할 수 있습니다.


답변

mbuffer를 살펴 보십시오 . 메모리 또는 메모리 매핑 파일 ( -t/ -T)로 버퍼링 할 수 있습니다 .


답변

이것은 기본적으로 부정적인 대답입니다. 둘 것으로 보인다 dd,도 mbuffer,도, 심지어 pv생산자에 의해 생성 된 데이터의 속도는 많이 달라질 수있는 경우에 작동하는 것은 특히, 모든 경우입니다. 아래에 몇 가지 테스트 사례를 제공합니다. 명령을 입력 한 후 약 10 초 정도 기다렸다가 입력을 기다리십시오 >(예 : 입력이 끝날 때까지 기다리십시오).

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

여기서을 입력 >한 후 5 초 동안 기다려야합니다. 즉, 제작자 (zsh 스크립트)가을 (를) 차단했습니다 sleep 5. 증가 bs32MB의 버퍼가 충분히 큰이 있지만 예를 들어 32M에 크기 것은 동작을 변경하지 않습니다. 나는 이것이 dd입력으로 진행되는 대신 출력의 블록 때문이라고 생각합니다 . oflag=nonblock데이터를 삭제하기 때문에 사용하는 것이 해결책이 아닙니다.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

mbuffer경우 첫 번째 줄 (foo0)이 즉시 나타나지 않습니다. 입력시 라인 버퍼링을 활성화하는 옵션이없는 것 같습니다.

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

pv경우 동작은와 유사합니다 dd. 더 나쁜 것은, 때때로 less터미널에서 더 이상 입력을받을 수 없기 때문에 터미널에 잘못된 일을하는 것입니다 . 예를 들어로 종료 할 수 없습니다 q.


답변

비표준 이동 : 소켓 버퍼 사용.

예:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

이를 위해 두 가지 추가 도구 인 buffered_pipelinemapopentounixsocket 을 구현했습니다.

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]


답변