왜 대용량 파일의 헤더;테일은 시간이 오래 걸리고 때로는 그렇지 않습니까?

왜 대용량 파일의 헤더;테일은 시간이 오래 걸리고 때로는 그렇지 않습니까?

저는 .txt 파일의 처음 10줄과 마지막 10줄을 읽는 bash 스크립트를 작성 중입니다. 시작(head)과 완료(tail)를 찾고 grep을 사용하여 발생 횟수를 비교합니다. 이러한 파일은 상당히 크기 때문에 전체 텍스트 대신 파일의 머리 부분과 끝 부분만 읽기로 결정했습니다. 그러나 스크립트를 실행하면 대용량 파일을 "완료"하는 데 오랜 시간이 걸립니다(처음 10줄과 마지막 10줄을 읽고 비교하는 작업이 포함되며 이 작업은 1~2분 밖에 걸리지 않습니다).

스크립트 출력 텍스트를 보면서 이 문제를 발견했습니다. 그래서 명령줄에서 직접 head/tail(스크립트에서 실행될 내용을 시뮬레이션하기 위해 grep 포함) 명령을 실행할 때 비슷한 시간이 걸리는지 확인하기로 결정했습니다. 놀랍게도 명령은 거의 즉시 실행되었습니다. 이상하다고 생각해서 다시 스크립트를 실행해 봤습니다. 이번에는 스크립트가 아직 head/tail/grep 명령을 실행하지 않은 다음 "큰" 파일에 도달할 때까지 이전에 걸린 파일을 통해 비명을 지릅니다.

bash가 명령 결과를 캐시처럼 저장합니까? 또한 이러한 명령의 가능한 원인은 다음과 같습니다.

 head -n 10 /file/path/myfile.txt | grep -w -c 'lead word'
 tail -n 10 /file/path/myfile.txt | grep -w -c 'end word'

실행하는데 그렇게 오래 걸리나요?

편집: 위의 헤더/꼬리 줄이 문제의 원인인 이유는 헤더/꼬리 줄을 개별적으로 수행할 때 인쇄해야 하는 에코 줄이 있기 때문이라고 생각합니다. 파일의 줄 크기를 확인해 보니 몇 분 만에 완성된 파일보다 그리 길지 않습니다.

기술적인 수준에서 헤드/테일 작동 방식에 대해 좀 더 자세히 설명해 줄 수 있는 사람이 있나요? 나는 파일의 "앞 x 줄/뒤 x 줄"에 대해 매우 기본적인 것을 이해하고 있습니다.

답변1

아니요, bash는 실행마다 출력이 변경될 수 있기 때문에 명령의 출력을 캐시하지 않습니다. bash는 파일이 다른 프로세스에 의해 수정되었는지 여부를 추적할 수 있는 신뢰할 수 있는 방법이 없습니다. 이는 매우 중요하므로 bash캐시되었는지 여부를 알 수 있습니다. 결과는 여전히 효율적입니다.

그러나 여기에는 다른 것이 있습니다. 셸(예 bash: )을 사용하면 시스템의 여러 부분과 동시에 상호 작용하게 됩니다. 예를 들어:

  • 껍질 자체
  • 여러 셸 및 기타 도구에서 사용되는 줄 편집 인터페이스인 GNU Readline
  • libc구현은 때때로 거의 모든 프로그램에서 혼란스러운 동작을 일으킬 수 있습니다.
  • 터미널 자체가 이상한 동작을 하고 실제로 응답할 수 있습니다.나만의 주문. (예를 들어, Backspack및 는 Delete사용할 수 없거나 서로 바꿔 사용할 수 있습니다.)
  • 터미널이 위치한 GUI 창입니다(해당되는 경우). 예를 들어,Ctrl특수 키 시퀀스(예: ++ 다음에 숫자가 오는 형식)를 사용하여 Shift터미널에 유니코드 문자를 입력 할 수 있습니다.u
  • 모든 모듈과 드라이버를 포함한 커널
  • 물론 하드웨어 자체가 과열되거나, 단락되거나, 전원이 꺼지는 등의 현상이 발생할 수 있습니다.

bash이 경우 가장 큰 기여자는 자체가 아니라 커널에 구현된 파일 시스템 수준 캐싱 메커니즘 이라고 말하고 싶습니다 . 파일을 한 번 읽으면 그 중 상당 부분이 파일 시스템 캐시에 저장됩니다. 이는 이 목적으로 예약된 메모리의 큰 덩어리입니다.

파일이 두 번째로 작동되면 셸은 물리적 하드웨어에서 다시 읽기를 트리거하지 않지만 캐시에서 파일 내용을 검색합니다. Bash에서 (다시) 수행하는 거의 모든 작업은 디스크 읽기에 비해 매우 빠릅니다. 이것이 느린 디스크 읽기가 손실되기 때문에 bash가 실제로 명령을 다시 실행하고 있다는 것을 알지 못하는 이유입니다.

관련 정보