임시 파일(아니요fifo/pipe)는 여러 판독기 스크립트로 모니터링해야 합니다. 각 스크립트는 다음 코드를 사용하여 백그라운드 프로세스를 사용하여 임시 파일을 모니터링합니다.
function file_relay {
# $1 is a regular file to read from
local bg_file
bg_file="$1"
# $2 is a fifo to relay to
local outfile
outfile="$2"
tail -f "$bg_file" | while read -r line
do
[[ ! -z "$line" ]] && { printf "%s" "$line" >>"$outfile"; }
done
}
시작 시 전체 파일을 읽은 다음 위의 함수가 수행하는 새 줄을 감시해야 합니다.
file_relay /tmp/examplefile /tmp/examplefifo &
각 스크립트는 또한 이 파일에 행을 출력합니다. 따라서 이것은 다중 저자 및 다중 독자 상황입니다.
문제는 파일로 리디렉션을 사용하고 문자열 끝에 개행 문자가 있어도 tail -f
전체 줄을 사용할 수 있을 때까지 기다리지 않는 경우가 있다는 것입니다. printf
이로 인해 읽고 있는 줄이 손상되고 마지막 줄의 첫 번째 단어가 이전 줄의 끝에 추가되어 다음과 같은 결과를 얻습니다.
This is one lineThis
바꾸다
This is one line
This is another line
해결하려는 printf
버퍼링 문제 tail -f
와 파일 주위에 쓰기를 사용하는 것 (위 함수에서 파일은 읽기 전용이므로 sync
전체 파일을 읽으려고 하기 전에 해당 라인을 강제로 tail
실행하는 방법을 모르겠습니다 sync
) . stdbuf
어디에도 아무런 영향을 미치지 않는 것 같고 -z
for 또는 문자열을 with 또는 other로 사용하거나 종료 tail
하는 것도 마찬가지입니다 . $'\0'
즉시 발생하는 것을 방지하는 유일한 방법은 루프가 시작되기 sync
전이지만 while
루프가 시작된 후에도 발생하는 것을 막지는 못합니다.
tail -f
강제로 전체 줄만 읽도록 하는 방법이 있나요 ?
답변1
짧은: 직접적이지 않음
길다: 이식성이 없다.POSIX), 하지만 Linux에만 관심이 있다면 파이프를 통해산출tail -f
무언가를 통해예라인 버퍼링. 예를 들어, 제안한 대로유닉스 명령 'tail'에 '--line-buffered' 옵션이 없습니다., GNU grep에는 --line-buffered
다음을 수행할 수 있는 옵션이 있습니다.
tail -f "$bg_file" | grep --line-buffered -E '^.*$'
그러나수동지적
--line-buffered
라인 버퍼링을 사용하세요.이는 성능 저하일 수 있습니다..
(FreeBSD동일한 옵션과 설명이 있습니다.오픈BSD 2004, 아니요POSIX하지만...).
문서에는 이에 대한 내용이 나와 있지 않지만2001년에 처음 제출됨나는 그것을 하는 데 시간이 걸렸다 fflush
.