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

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

때로는 보고나 다른 보조 사용을 위해 파이프라인에 무언가를 삽입하고 싶습니다. 그것은 그렇게 간단할 수도 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모든 백그라운드 작업이 완료될 때까지 기다립니다. 두 프로세스는 거의 동시에 완료됩니다.

프로세스 중 하나가 눈에 띄게 느린 경우 tee표준 출력 파이프나 기록 중인 명명된 파이프를 차단할 수 있으므로 전체 프로세스 속도가 크게 느려질 수 있습니다.편집하다: 또한, 작업자 프로세스가 실패하면 tee가 깨진 파이프와 함께 종료되므로 이제 더 많은 실패 모드가 있습니다.

관련 정보