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


14

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

$ producer | buf | consumer

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


저도보고 싶습니다
Antti Haapala

stdbuf도구는 것으로 보인다 size매개 변수입니다. 그래도 작동하는지 확실하지 않습니다.
CMCDragonkai

답변:


14

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


무한한 양의 데이터로 이것을 수행하는 방법이 있습니까? 내가 알 수있는 한, -B를 숫자로 제공해야하며 생산자가 소비자보다 훨씬 앞서면 생산자가 다시 느려집니다. 여러 소비자 ( producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2) 가있는 상황에서는 다시 속도가 느려질 수 있습니다.
Daniel H

나는 pv수백 번 사용 했지만 이것을 전혀 몰랐습니다. 정말 대단해, ​​고마워!
Rucent88

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null-나는 양쪽 pv끝이 매끄 럽기를 기대합니다 (1GB가 앞당겨도). mbuffer
Vi

9

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

producer | dd obs=64K | consumer

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


표준 유틸리티를 사용하는 경우 +1이지만 pv사용하기에 더 좋을 수도 있습니다 (진행률 표시).
Totor

2
실제로 읽기 속도와 쓰기 속도가 분리됩니까? dd한 번에 하나의 블록 만 저장하는 것처럼 보이 므로 블록 크기를 생성하는 데 걸리는 시간만큼 모든 것을 지연시킵니다. 내가 틀렸다면 정정 해주세요. 또한이 버퍼링을 무제한 크기로 확장 할 수 있습니까 아니면 블록 크기에 입력 한 것만으로 확장 할 수 있습니까?
Daniel H

@DanielH-이제 그렇습니다.
mikeserv

7

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


내가 다른 사람들에게 물었을 때 필요한만큼 버퍼에 알리는 방법이 있습니까, 아니면 최대 크기입니까? 이러한 프로그램의 대부분이 최대 크기를 가지고 있고 더 작은 버퍼의 링크 된 목록 (또는 다른 임의의 크기 큐 구현)을 사용하지 않는 개념적 이유가 있습니까?
Daniel H

메모리 부족 오류를 방지 할 수 있습니다. 원하는 경우 옵션을 사용하여 매우 큰 버퍼 (4GB 정도)를 설정할 수 있습니다 (시도하십시오).
David Balažic

1

이것은 기본적으로 부정적인 대답입니다. 둘 것으로 보인다 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.


0

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

예:

# 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] [         <=>      ]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.