awk의 꼬리는 inotifywait와 다르게 동작합니다.

awk의 꼬리는 inotifywait와 다르게 동작합니다.

awktail -finotifywait -mvs. 의 출력을 분석할 때 동작이 다릅니다 . 특히, 일치하는 문자열을 검색 중인데 해당 문자열 awk이 나타나면 종료하고 싶습니다. 이는 에서는 잘 작동 tail -f하지만 의 경우에는 inofitywaitawk번 트리거해야 합니다. 왜 이런거야?


재현 가능한 예:

두 경우 모두 특정 문자열("OPEN")을 검색하고 이를 특수 종료 코드로 표시한다고 가정합니다. inotofywait잠시 기다린 후(시간이 좀 걸립니다) 트리거하고 종료 코드를 반환해 보겠습니다 . 의사코드:

 command | awk-analysis || get-non-0-exit-code & trigger

모든 것이 그보다 낫다tail -f

다음은 a) 행을 인쇄하고, b) 종료 코드를 반환하고, c) 종료합니다. 예상대로.

tail -f test.file | awk '/OPEN/ { print $0 ; exit 100 }' || echo $? &
  { sleep 2 ; echo OPEN > test.file ; }

그러나inotifywait -m

결과는 완전히 달랐습니다.

inotifywait -m -e OPEN | awk '/OPEN/ { print $0 ; exit 100 }' || echo $? &
  { sleep 2 ; touch test.file ; }

이렇게 하면 행이 인쇄되지만( inotifywait트리거되어 awk표시됨) 종료 코드가 표시되거나 종료되지 않습니다. 이와 같은 또 다른 트리거만이 touch test.file이를 중지할 수 있습니다.awk

어쩌면 제어 문자일까요?

여기에 신호 목적이 누락되었을 수도 있다고 생각하여 분석을 위해 (상위 폴더의 결과 파일, 그렇지 않으면 두 번째 "OPEN"이 트리거됨 )을 awk사용해 보았습니다 .cat -Ainotifywait

tail -f test.file | tee >(cat -A >../stream) | ....
cat ../stream
OPEN$

그리고

inotifywait -m -e OPEN | tee >(cat -A >../stream) | ....
cat ../stream
./ OPEN test.file$

따라서 보이지 않는 제어 문자가 누락되지 않습니다.

이 행동의 이유는 무엇입니까?

줄바꿈을 놓쳤나요? awk이 줄은 인쇄되지만 exit동일한 코드 블록에서 명령을 실행 하지 않는 이유는 무엇입니까 ? 그런데 왜 작동합니까 tail?


버전

awk --verison:GNU Awk 4.2.1, API: 2.0(GNU MPFR 4.0.2, GNU MP 6.1.2)

inotifywait -h: inotifywait 3.14

tail --verison:tail(GNU coreutils) 8.30


Kusalananda의 의견을 바탕으로 편집:

꼬리 -f

test.file존재하며 다음 내용이 있습니다.

*사례 1

OPEN
spam

*사례 2

spam
OPEN

*사례 3(파일이 비어 있음)

위의 트리거가 실행되고 있지 않습니다.

tail -f test.file | awk '/OPEN/ {print $0 ; exit 100 }' || echo $?

사례 1 & 2: 일치하는 줄, 종료 코드를 즉시 반환하고 종료합니다.

사례 3: 기다려서 다른 터미널을 열고 echo OPEN >> 3/또는 echo OPEN > 3문자열을 반환하고 종료 코드를 종료합니다.

답변1

echo $?전체 파이프라인(이전 코드 ||)이 종료된 후에 실행됩니다.

종료 inotifywait … | awk … || echo …후에도 여전히 실행 중입니다 . 더 많이 쓰려고 할 때만 얻습니다. 이 지점에 다시 도달하여 트리거해 보세요.awkinotifywaitSIGPIPEtouch test.fileecho

반면에 퇴장 후 바로 종료하는 tail것은tail -f … | awk …awkGNU는 tail이러한 상황을 감지하기 위해 특별한 조치를 취합니다..


inotifywait를 사용하여 이를 재현하려면 PID를 전달하고 awk를 통해 SIGPIPE를 보내야 합니다.

{ inotifywait  -m -e OPEN ./  & echo $! ; } |
awk 'NR==1 {pid=$0}
     /OPEN/ {print $0,pid
             system("echo kill -13 "pid)
             exit 122  }' ||
echo $? 

관련 정보