왜“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). 같은 지향 도구 스트리밍 sed및 awk필요도 파일의 시작 또는 끝을 : 그들은 버퍼에서 작동합니다.


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.