주기적으로 파이프라인을 보고 마지막 보기 이후 생성된 새 출력을 추출합니다.

주기적으로 파이프라인을 보고 마지막 보기 이후 생성된 새 출력을 추출합니다.

파이프의 증가하는 출력(예: 출력 inotifywait)을 읽고 있습니다.

정기적으로 파이프라인 출력을 확인하고 마지막으로 본 이후 생성된 새 출력을 추출해야 합니다.

쉘 스크립트에서 이 작업을 어떻게 수행할 수 있습니까? Google 검색에 사용할 키워드를 모르겠습니다.

답변1

파이프의 데이터는 한 번만 읽을 수 있습니다. "새 콘텐츠" 부분은 간단합니다. inotifywait를 사용하여 명명된 파이프를 생성하고 mkfifo출력을 해당 파이프로 리디렉션 >하고 주기적으로 파이프를 읽으십시오.

더 까다로운 부분은 차단 없이 어딘가에 쓰기 위해 열리는 읽기 파이프입니다. dd는 할 수 있어요.

이것은 파이프를 생성하고 지속적으로 쓰는 데 사용하는 설정입니다.

mkfifo foo
( while true ; do date; sleep 1 ; done ) > foo

읽지 않은 모든 데이터를 읽습니다.

dd iflag=nonblock if=foo bs=1M count=1 of=buffer.txt

of=...원하는 출력 파일로 변경할 수 있습니다 .

조만간 파이프에서 부분적인 줄을 얻게 될 것이므로 스크립트가 이를 처리할 수 있는지 확인하십시오. 설명하는 활동 유형의 경우 버퍼가 개행으로 끝날 때까지 추가 모드에서 dd를 반복하는 것이 좋습니다.

buf=buffer.txt
pipe=foo
> $buf # empty the buffer
until [[ $( tail -c1 $buf | od -a ) == *nl* ]] # nl means newline
do
  dd iflag=nonblock oflag=append conv=notrunc if=$pipe bs=1M count=1 of=$buf
  ls -l $buf # see how it grows
  sleep 1 # if the writer dies, this loop will be infinite and we don't want to kill the CPU
done
do_stuff.sh < $buf
# rm $buf

편집: 터미널에서 inotifywait를 말하고 모든 새 콘텐츠를 덤프하려는 것 같습니다. 이 방법이 더 쉽습니다. whatsnew.sh와 유사한 파일을 만듭니다.

#!/bin/bash
echo "waiting for first output ... "
while true
do
    n=0
    while read -t0.1 line
    do
        echo "[$line]"
        (( n++ ))
    done
    read -p "$n new lines.  Press any key to try again... " -n1 -s </dev/tty
    echo
done

그런 다음 시작하십시오.

inotifywait | whatsnew.sh

관련 정보