tail은 전체 파일을 읽습니까? 텍스트 tail파일을 원하면

tail25GB 텍스트 tail파일을 원하면 명령이 전체 파일을 읽습니까?

파일이 디스크에 흩어져있을 수 있기 때문에 파일이 필요하다고 생각하지만 그러한 내부 구조를 잘 이해하지 못합니다.



답변

아니요, tail전체 파일을 읽지 않고 끝까지 검색 한 다음 예상 줄 수에 도달 할 때까지 블록을 뒤로 읽은 다음 파일 끝까지 올바른 방향으로 행을 표시하고 -f옵션이 사용되는 경우 파일 .

그러나 tail파이프에서 읽을 때와 같이 검색 할 수없는 입력이 제공된 경우 전체 데이터를 읽는 것 외에는 선택의 여지가 없습니다.

마찬가지로, 지원되는 경우 tail -n +linenumber구문 또는 tail +linenumber비표준 옵션 을 사용하여 파일 시작 부분부터 시작하여 줄을 찾도록 요청 tail하면 전체 파일을 읽습니다 (중단되지 않은 경우).


답변

tail자신이 어떻게 작동 하는지 볼 수 있습니다 . 내 파일 중 하나에 대해 read세 번 수행되며 총 약 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


답변

파일이 디스크에 흩어져있을 수 있기 때문에 [파일을 순차적으로 읽어야한다] 고 생각하지만 그러한 내부 구조를 잘 이해하지 못합니다.

아시다시피, tail파일의 끝 부분 (시스템 호출 lseek)을 찾고 뒤로 작동합니다. 그러나 위에서 인용 한 말에서 “꼬리가 파일의 끝을 찾기 위해 디스크의 어디에 있는지 어떻게 알 수 있습니까?”

대답은 간단하다 : 꼬리는 모른다. 사용자 수준 프로세스는 파일을 연속 스트림으로 인식하므로 tail파일 시작의 오프셋을 알 수 있습니다. 그러나 파일 시스템에서 파일의 “inode”(디렉토리 항목)는 파일 데이터 블록의 물리적 위치를 나타내는 숫자 목록과 연관됩니다. 파일을 읽을 때 커널 / 장치 드라이버는 필요한 부분을 파악하고 디스크상의 위치를 ​​파악하여 가져옵니다.

그것은 우리가 운영 체제를 가지고있는 종류입니다. 따라서 파일 블록이 어디에 흩어져 있는지 걱정할 필요가 없습니다.


답변

head또는 전체 파일을 읽는 tail 것으로 보이면 파일에 줄 바꿈 문자가 거의 없거나 전혀 없기 때문일 수 있습니다 . 몇 달 전에 문자열이 아닌 공백이 없어도 직렬화 된 매우 큰 (기가 바이트) JSON 블롭 으로이 문제를 해결했습니다.

GNU head / tail이 있다면 line 대신 -c N첫 번째 / 마지막 N 바이트 를 인쇄하는 데 사용할 수 있지만 불행히도 이것은 POSIX 기능이 아닙니다.


답변

당신은에서 볼 수 있듯이 소스 코드 라인 (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.  */


답변