스트림을 복제하고 두 부분을 스트리밍 방식으로 처리하는 방법은 무엇입니까?

스트림을 복제하고 두 부분을 스트리밍 방식으로 처리하는 방법은 무엇입니까?

때로는 보고나 기타 보조 용도로 파이프라인에 무언가를 삽입하고 싶을 때가 있습니다. 처럼 간단할 수도 있고, 파이썬 스크립트와 같이 wc -l더 복잡한 것일 수도 있습니다. awk다음과 같이 파이프라인을 실행하는 것이 좋을 것입니다.

zcat my_data_file.gz \
| wc -l > /tmp/linecount
| process_data.py

문제는 대부분의 유틸리티가 데이터를 표준 출력으로 바로 보내지 않는다는 것입니다. tee임시 파일에 데이터를 쓸 수 있지만 모든 작업이 완료될 때까지 기다려야 합니다.

zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py && \
wc -l /tmp/f > /tmp/linecount && rm /tmp/f

이는 최적이 아닙니다. 매우 오랫동안 실행되는 파이프라인일 수 있습니다. 나는 아날로그의 중간 결과를 wc더 빨리 보고 싶을 수도 있습니다. 모든 데이터를 임시 파일에 저장하고 싶지 않을 수도 있습니다.

답변1

이에 대한 대체를 사용 tee하고 처리 할 수 있습니다.>(...)

zcat my_data_file.gz |

# Count number of lines in stream
tee >(wc -l > /tmp/linecount) |

# Further processing
process_data.py

파이프는 줄 연속에 사용될 수 있으며 명령 사이에 주석이 삽입될 수 있다는 점에 유의하세요. 이는 복잡한 파이프라인을 구축할 때 좋은 기능입니다.

답변2

완전히 효율적이지는 않지만 다음을 사용하여 이를 달성할 수 있습니다.명명된 파이프를 사용하여 만들 수 있습니다.mkififo(1)

질문의 예를 들면 다음과 같습니다.

mkfifo /tmp/f

wc -l /tmp/f > /tmp/linecount &

zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py &

wait

rm /tmp/f

파이프라인과 파이프라인 &모두에 추가된 내용을 참고하세요 . wc이는 쉘이 작업을 백그라운드로 푸시한다는 것을 의미합니다. 그런 다음 호출은 wait모든 백그라운드 작업이 완료될 때까지 기다립니다. 두 프로세스 모두 거의 동시에 완료됩니다.

프로세스 중 하나가 상당히 느린 경우 teestdout 파이프나 기록 중인 명명된 파이프가 차단될 수 있으므로 전체 속도가 크게 느려질 수 있습니다.편집하다: 또한 보조 프로세스가 실패하면 파이프가 파손되어 tee가 종료되므로 이제 더 많은 실패 모드가 있습니다.

관련 정보