쉘 표준 출력을 두 개의 명령으로 변환하고 프로그램이 중단됨

쉘 표준 출력을 두 개의 명령으로 변환하고 프로그램이 중단됨

배열 백분위수를 계산하는 샘플 셸 명령이 있습니다.

$ time zcat input.txt.gz | head -n 999999 | awk 'BEGIN{FS="\t"}{print $13}' | st
--percentile=97.5
75

real    0m3.532s
user    0m8.584s
sys     0m0.648s

2개의 백분위수로 숫자를 계산하고 싶기 때문에 속도가 빠르다는 것을 알 수 있습니다. tee를 사용하여 stdout을 명령으로 리디렉션합니다.

mkfifo output_txt;
zcat input.txt.gz | head -n 999999 |
   awk 'BEGIN{FS="\t"}{print $13}' |
   tee >(st --percentile=2.5) >> output_txt |
   st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt

그러나 그것은 밖으로 나가서 붙어 있지 않습니다.

fifo를 사용해야 할 것 같아서 다음으로 변경했습니다.

echo "" > output_txt;
zcat input.txt.gz | head -n 999999 |
   awk 'BEGIN{FS="\t"}{print $13}' |
   tee >(st --percentile=2.5) >> output_txt |
   st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt

실행되지만 긴 숫자 목록을 출력하고 프로그램이 각 행의 분위수를 계산하는 것처럼 보입니다.

input.txt생성할 수 있다

for ((i=0; i<999999; i++)); do
  number=$(awk 'BEGIN{print int(rand()*1000)/10}')
  echo $number >> input.txt
done

=====업데이트======

@ilkkachu가 언급했듯이 다음 명령은 잘 작동합니다.

echo "" > output_txt;
zcat input.txt | head -n 999999 |
   awk 'BEGIN{FS="\t"}{print $13}' |
   tee >(st --percentile=2.5 >> output_txt) |
   st --percentile=97.5 >> output_txt;
cat output_txt; rm output_txt

하지만 fifo를 사용할 때는 작동하지 않습니다(여전히 붙어 있음).

업데이트: @Paul_Pedant

FIFO는 파이프입니다. 가져오는 데이터가 일부 시스템 제한(아마도 4096바이트(POSIX 최소) 또는 64KB(일반적인 Linux) 또는 기타 제한)에 도달하면 fifo는 다른 프로세스가 일부 데이터를 읽을 때까지 쓰기를 차단합니다.

이것이 fifo를 사용할 때 막히는 이유를 설명한다고 생각합니다.

관련 정보