FIFO를 통해 출력을 분배

FIFO를 통해 출력을 분배

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

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

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

처음에는 작동하는 것 같으나 갑자기 멈추고 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에서 stdin, P2에서 stdout. 따라서 tee출력을 P2 myfifo와 P2 모두에 기록합니다.
  • grep -E "errors|warnings" myfifo > errors.logmyfifo: P2의 stdin이지만 파일 이름( )을 에 전달하므로 해당 stdin에서 읽지 않습니다 grep. grepstdout은 으로 가고 errors.log, P3에는 아무 것도 쓰지 않습니다.
  • cat myfifo: P3의 stdin이지만 cat파일 이름이 주어지면 대신 읽습니다. 따라서 둘 다 grep동시에 cat읽습니다 myfifo.

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

관련 정보