tail
25GB 텍스트 파일을 원하는 경우 tail
이 명령이 전체 파일을 읽습니까?
아마도 파일들이 디스크 여기저기에 흩어져 있기 때문에 그럴 것이라고 생각하지만, 내부가 이렇다는 것은 잘 이해가 되지 않습니다.
답변1
아니요, tail
전체 파일을 읽는 대신 끝까지 살펴본 다음 예상 줄 수에 도달할 때까지 뒤로 청크를 읽은 다음 파일 끝까지 올바른 방향으로 줄을 표시하고 파일 모니터링을 계속할 수도 있습니다. -f
해당 옵션이 사용됩니다).
다만, tail
탐색할 수 없는 입력이 제공되면 파이프에서 읽는 경우와 같이 전체 데이터를 읽을 수밖에 없다는 점에 유의하세요.
마찬가지로, 파일의 시작 부분에서 시작하는 줄을 찾으라는 요청을 받을 때 tail -n +linenumber
구문이나 tail +linenumber
비표준 옵션을 사용하여 지원된다면 tail
분명히 전체 파일을 읽을 것입니다(중단되지 않는 한).
답변2
tail
어떻게 작동하는지 직접 확인할 수 있습니다 . 보시다시피, 내 파일 중 하나가 read
3번 실행되어 총 약 10K 바이트를 읽었습니다.
strace 2>&1 tail ./huge-file >/dev/null | grep -e "read" -e "lseek" -e "open" -e "close"
open("./huge-file", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_END) = 80552644
lseek(3, 80551936, SEEK_SET) = 80551936
read(3, ""..., 708) = 708
lseek(3, 80543744, SEEK_SET) = 80543744
read(3, ""..., 8192) = 8192
read(3, ""..., 708) = 708
close(3) = 0
답변3
파일이 디스크에 분산되어 있기 때문에 [파일을 순차적으로 읽어야] 해야 할 것 같은데, 이런 내부는 잘 이해가 되지 않습니다.
지금까지 알고 있듯이 tail
파일의 끝을 찾아서(시스템 호출을 사용하여 lseek
) 역방향으로 작업하면 됩니다. 하지만 위에 인용된 댓글에서 궁금하신 점은"tail은 디스크에서 파일의 끝을 찾을 수 있는 위치를 어떻게 알 수 있나요?"
대답은 간단합니다. Tail은 모릅니다. 사용자 수준 프로세스는 파일을 연속 스트림으로 처리하므로 모든 사람이 tail
파일 시작 부분의 오프셋을 알 수 있습니다. 그러나 파일 시스템에서 파일의 "inode"(디렉토리 항목)는 파일 데이터 블록의 물리적 위치를 나타내는 숫자 목록과 연결됩니다. 파일을 읽을 때 커널/장치 드라이버는 필요한 부분을 파악하고 디스크에서의 해당 위치를 결정하여 가져옵니다.
이것이 바로 우리 운영 체제의 목적입니다. 따라서 파일 블록이 어디에 흩어져 있는지 걱정할 필요가 없습니다.
답변4
당신처럼소스 코드525행에서 구현 주석을 볼 수 있습니다.
/* Print the last N_LINES lines from the end of file FD.
Go backward through the file, reading 'BUFSIZ' bytes at a time (except
probably the first), until we hit the start of the file or have
read NUMBER newlines.
START_POS is the starting position of the read pointer for the file
associated with FD (may be nonzero).
END_POS is the file offset of EOF (one larger than offset of last byte).
Return true if successful. */