FIFO를 통해 출력 분배

FIFO를 통해 출력 분배

나는 다음을 사용하여 매우 긴 make 출력을 배포하려고 합니다.

mkfifo myfifo 
make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo

아이디어는 출력의 하위 집합을 로그 파일에 복사하고 전체 출력은 콘솔의 표준 출력으로 리디렉션한다는 것입니다.

처음에는 작동하는 것 같으나 갑자기 멈추고 Ctrl-Z를 누를 때까지 정지 상태를 유지합니다.

프로세스 대체 활용

make 2>&1 | tee >(grep -E "errors|warnings" > errors.log)

쉘은 컴파일할 때 기본적으로 POSIX 표준을 엄격하게 따르기 때문에 불가능합니다.

플랫폼 - 우분투 스타일 배포판입니다. shell bash 4.2 (하나만 사용 가능)

답변1

저것

make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo
          P1           P2                                              P3

명령은 아무 의미가 없습니다. 파이프를 사이에 두고 이 4개의 명령을 동시에 시작합니다.

  • make 2>&1: stdout 및 stderr은 P1으로 이동합니다.
  • tee myfifo: 표준 입력은 P1에서, 표준 출력은 P2로갑니다. 따라서 tee출력은 P2 myfifo와 P2에 기록됩니다.
  • grep -E "errors|warnings" myfifo > errors.logmyfifo: P2의 표준 입력에서 가져오지만 파일 이름( ) 을 전달하므로 grep표준 grep입력에서 읽지 않습니다. 표준 출력은 으로 가고 errors.logP3에는 아무 것도 기록되지 않습니다.
  • cat myfifo: P3의 표준 입력이지만 cat파일 이름이 주어지기 때문에 다시 읽습니다. 그래서 두 가지를 grep동시에 읽습니다.catmyfifo

P2에서 아무것도 읽지 않으므로 teeP2가 가득 차면 정지됩니다. 읽은 부분도 표시되지 않습니다 cat.myfifogrep

make 2>&1 | tee myfifo | grep -e errors -e warnings > errors.log | cat myfifo

말씀하신 내용에 더 가깝다고 봅니다. 다시 말하지만 P3은 사용되지 않지만 |동시에 시작 cat하고 기다리는 데 사용합니다 .

아니면 이렇게 할 수도 있습니다:

make 2>&1 | tee myfifo & grep -e errors -e warnings > errors.log
wait

더 많은 s가 필요하면 grep더 많은 fifo가 필요합니다.

make 2>&1 | tee fifo2grep1 fifo2grep2 &
grep errors fifo2grep1 > errors.log &
grep warnings fifo2grep2 > warnings.log
wait

지원되는 시스템에서는 /dev/fd/x다음을 수행할 수도 있습니다.

make 2>&1 | { tee /dev/fd/3 | grep -e errors -e warnings 3>&-; } 3>&1

(이것은 일반적으로 이를 지원하는 쉘에서 프로세스 대체가 수행되는 작업입니다.)

2초이면 grep다음과 같습니다.

make 2>&1 |
 {
   {
     tee /dev/fd/3 /dev/fd/4 |
       grep errors > errors.log 3>&- 4>&-
   } 4>&1 |
     grep warnings > warnings.log 3>&-
 } 3>&1

답변2

이후에는 grep -E "errors|warnings" myfifo > errors.log파이프에 더 이상 데이터가 포함되지 않습니다. 따라서 cat myfifo파이프에서 읽는 다음 명령이 차단됩니다.

귀하의 질문을 올바르게 이해했다면 모든 메시지를 stdout으로 인쇄하고 모든 오류 및 경고 메시지를 errors.log.

 mkfifo pipe1 pipe2 
 make 2>&1 | tee pipe1 pipe2 | grep -E "errors|warnings" pipe1 > errors.log | cat pipe2

관련 정보