왜“tail -f… | tail”가 출력을 생성하지 못합니까?


36

다음 명령이 출력을 생성하지 않는 이유는 무엇입니까?

$ tail -f /etc/passwd | tail

buffering 에 대해 읽은 후 다음을 시도했지만 아무 소용이 없었습니다.

$ tail -f /etc/passwd | stdbuf -oL tail

다음은 출력을 생성합니다.

$ tail /etc/passwd | tail

이것도 마찬가지입니다 :

$ tail -f /etc/passwd | head

테일 버전 8.21 (GNU coreutils)을 사용하고 있습니다.


17
π의 마지막 10 자리는 무엇입니까?
Keith Thompson

답변:


15

유닉스에서 모든 것을 보았다고 생각했습니다. 이 질문은 저의 밀수에서 나를 때렸습니다. 정말 좋은 질문입니다!

tail마지막 X 줄을 보여줍니다. tail -f시작시 파일의 마지막 X 줄을 표시 한 다음 inotify와 같은 일부 OS 매직을 사용하여 모니터링하고 새 줄을 표시합니다.

작업을 수행하려면 tail파일 끝을 찾을 수 있어야합니다. 경우 tail파일의 끝을 찾을 수 없습니다 "마지막"이 정의되지 않기 때문에, 그것은 마지막으로 X 선을 표시 할 수 없습니다. 그래서 어떻게 않습니다 tail이 경우에합니까? 파일의 끝을 찾을 때까지 기다립니다.

이걸 고려하세요:

$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f

에서 파일의 끝이 절대 없기 때문에이 작업은 진행되지 않는 것 같습니다 chatter.

tail파일 시스템 파이프에서 마지막 행을 제공 하도록 요청하면 동일한 동작을 얻습니다 . 치다:

$ mkfifo test.pipe
$ tail test.pipe

stdbuf인식 된 문제를 해결하는 것은 고귀한 시도였습니다. 그러나 중요한 사실은 I / O 버퍼링이 근본 원인이 아니라는 것입니다. 명확한 파일 끝이 없다는 것입니다. 당신이 체크 아웃하는 경우 tail.c 소스 코드를 , 당신은 볼 수 있습니다 file_lines기능 댓글이 읽습니다

END_POS는 EOF의 파일 오프셋 (마지막 바이트의 오프셋보다 큰 것)입니다.

그것이 마법입니다. tail이 모든 구성에서 작동하려면 파일 끝이 필요합니다. head그 제한이 없으므로 파일 시작 만하면됩니다 (필요하지 않을 수도 있습니다 head test.pipe). 같은 지향 도구 스트리밍 sedawk필요도 파일의 시작 또는 끝을 : 그들은 버퍼에서 작동합니다.


37

tail -f의 꼬리는 실제로 현재에 알려지지 않은 것이므로 다음 tail은 어떻게 알 수 있습니까? 한편, tail -f머리는 이미 알려진 것이므로 처리 될 수있다.

또는 더 간단하게 말하면 tail파일의 끝과 관련이 있지만 출력 스트림 tail -f에는 EOF가 없습니다 (적어도 종료하기 전에는 안 됨).

첫 번째 tailpid 를 찾아서 죽이면 두 번째 결과 볼 수 있습니다 .


21

기술 답변

스트림을 입력으로 실행하는 경우 스트림을 읽을 때 채우는 라인 버퍼를 tail유지 n하지만 스트림의 끝에 도달 할 때까지 해당 라인을 출력 할 수 없습니다 (예 : EOF입력에서 읽으려고 할 때 특수 코드를 수신함) 흐름. 호출 tail -f이 종료되지 않으므로 스트림을 닫지 않으므로 해당 스트림의 마지막 10 개 라인을 리턴 할 수 없습니다.


3

의 기능은 tail입력 또는 파일의 마지막 부분 ( "꼬리")을 표시하는 것입니다. (옵션 -f은 나중에 수행하는 작업에 관한 것이므로 여기서는 관련이 없습니다.)

파일에 대해 생각해 봅시다 :

파일마지막 부분은 무엇입니까 ? 파일
마지막 n 줄 이라고 가정 해 봅시다 .

i입력 파일의 줄 을 읽을 때 인쇄할지 여부를 결정하는 방법은 무엇입니까?
우리는 그것이 마지막 부분에 있는지 여부를 알지 못합니다. 마지막 줄이 무엇인지 알 수 없기 때문입니다. 이제 인쇄 할 수 없습니다 .

우리는해야 할 선을 유지 분명히 될 때까지 마지막의 부품입니다 n우리가 알고 있기 때문에, 선 또는 더 이상 그것의 일부가 될 수 있습니다 n더 라인

이제 파일끝 부분에 도달 하면 마지막 n줄이 실제로 n파일 의 마지막 줄임을 알 수 있습니다.

이제는

tail -f /etc/passwd | tail

첫 번째 tail는 파일을 읽은 다음 파일에서 더 많은 데이터얻기 위해 기다립니다 . 따라서 읽은 파일의 끝에 올 때 파일의 끝을 두 번째 꼬리에 알리지 않습니다. 그없이 두 번째 tail 결코 통지하지 도착 , 파일의 끝은 그래서 할 수 알아 결코 그것이 인쇄해야합니다 마지막 선이되는입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.