GNU grep 2.24 RTFS
결론 : 2와 2의 경우 만 :
NUL
예를 들어 printf 'a\0' | grep 'a'
C99에 따른 인코딩 오류 mbrlen()
, 예 :
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
때문에 \x80
UTF-8 유니 포인트의 첫 번째 바이트가 될 수 없습니다 : UTF-8 - 설명 | en.wikipedia.org
또한 Stéphane Chazelas가 언급했듯이 grep이 파일을 이진 파일로 간주하게 만드는 이유는 무엇입니까? | 유닉스 및 리눅스 스택 교환에서 , 이러한 검사는 TODO 길이의 첫 번째 버퍼 읽기까지만 수행됩니다.
첫 번째 버퍼 읽기까지만
따라서 매우 큰 파일 중간에 NUL 또는 인코딩 오류가 발생하면 어쨌든 잘릴 수 있습니다.
이것이 성능상의 이유라고 생각합니다.
예 : 줄을 인쇄합니다 :
printf '%10000000s\n\x80a' | grep 'a'
그러나 이것은하지 않습니다 :
printf '%10s\n\x80a' | grep 'a'
실제 버퍼 크기는 파일을 읽는 방법에 따라 다릅니다. 예 : 비교 :
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
을 사용하면 sleep
프로세스가 잠자기 때문에 첫 번째 행이 1 바이트 길이 인 경우에도 grep에 전달되고 두 번째 읽기는 파일이 이진인지 확인하지 않습니다.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
stderr 오류 메시지가 인코딩 된 위치를 찾으십시오.
git grep 'Binary file'
우리를 이끌어줍니다 /src/grep.c
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
이러한 변수의 이름이 잘 정해지면 기본적으로 결론에 도달했습니다.
encoding_error_output
빠른 grepping for encoding_error_output
는 그것을 수정할 수있는 유일한 코드 경로가 통과한다는 것을 보여줍니다 buf_has_encoding_errors
.
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
그럼 그냥 man mbrlen
.
nlines_first_null 및 nlines
다음과 같이 초기화 됨 :
intmax_t nlines_first_null = -1;
nlines = 0;
따라서 null이 발견 0 <= nlines_first_null
되면 true가됩니다.
TODO는 nlines_first_null < nlines
언제 거짓 일 수 있습니까? 게으르다
POSIX
바이너리 옵션 grep을 정의하지 않음 -패턴을 찾기 위해 파일 검색 | pubs.opengroup.org 및 GNU grep 은이를 문서화하지 않으므로 RTFS가 유일한 방법입니다.
--null-data
NUL
구분 기호 인 경우 유용 할 수 있습니다 .