읽기 및 쓰기 속도를 분리하기 위해 파이프 라인에 연결할 수있는 유틸리티가 있습니까?
$ producer | buf | consumer
기본적 buf
으로 가능한 빨리 입력을 읽고 메모리에 저장하여 최대한 빨리 실행 consumer
하는 동안 달콤한 시간이 걸릴 수 있는 유틸리티 를 원합니다 producer
.
stdbuf
도구는 것으로 보인다 size
매개 변수입니다. 그래도 작동하는지 확실하지 않습니다.
읽기 및 쓰기 속도를 분리하기 위해 파이프 라인에 연결할 수있는 유틸리티가 있습니까?
$ producer | buf | consumer
기본적 buf
으로 가능한 빨리 입력을 읽고 메모리에 저장하여 최대한 빨리 실행 consumer
하는 동안 달콤한 시간이 걸릴 수 있는 유틸리티 를 원합니다 producer
.
stdbuf
도구는 것으로 보인다 size
매개 변수입니다. 그래도 작동하는지 확실하지 않습니다.
답변:
pv
(파이프 뷰어) 유틸리티는이합니다 (로 할 수있는 -B
보고서를 진행 제공을 포함하여 더 많은 옵션)합니다.
producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2
) 가있는 상황에서는 다시 속도가 느려질 수 있습니다.
pv
수백 번 사용 했지만 이것을 전혀 몰랐습니다. 정말 대단해, 고마워!
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
당신은 사용할 수 있습니다 dd
:
producer | dd obs=64K | consumer
모든 유닉스에서 사용할 수 있습니다.
pv
사용하기에 더 좋을 수도 있습니다 (진행률 표시).
dd
한 번에 하나의 블록 만 저장하는 것처럼 보이 므로 블록 크기를 생성하는 데 걸리는 시간만큼 모든 것을 지연시킵니다. 내가 틀렸다면 정정 해주세요. 또한이 버퍼링을 무제한 크기로 확장 할 수 있습니까 아니면 블록 크기에 입력 한 것만으로 확장 할 수 있습니까?
이것은 기본적으로 부정적인 대답입니다. 둘 것으로 보인다 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
. 증가 bs
32MB의 버퍼가 충분히 큰이 있지만 예를 들어 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_pipeline 및 mapopentounixsocket 을 구현했습니다.
$ ./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] [ <=> ]