GNU grep 2.24 RTFS
Kết luận: chỉ 2 và 2 trường hợp:
NUL
, ví dụ printf 'a\0' | grep 'a'
lỗi mã hóa theo C99 mbrlen()
, ví dụ:
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
bởi vì \x80
không thể là byte đầu tiên của điểm Unicode UTF-8: UTF-8 - Mô tả | vi.wikipedia.org
Hơn nữa, như được đề cập bởi Stéphane Chazelas Điều gì khiến grep coi một tệp là nhị phân? | Unix & Linux Stack Exchange , những kiểm tra đó chỉ được thực hiện cho đến lần đọc bộ đệm đầu tiên có độ dài TODO.
Chỉ đọc đến bộ đệm đầu tiên
Vì vậy, nếu một lỗi NUL hoặc mã hóa xảy ra ở giữa một tệp rất lớn, thì nó có thể bị lỗi.
Tôi tưởng tượng điều này là vì lý do hiệu suất.
Ví dụ: cái này in dòng:
printf '%10000000s\n\x80a' | grep 'a'
nhưng điều này không:
printf '%10s\n\x80a' | grep 'a'
Kích thước bộ đệm thực tế phụ thuộc vào cách đọc tệp. Ví dụ: so sánh:
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
Với sleep
, dòng đầu tiên được chuyển đến grep ngay cả khi nó chỉ dài 1 byte vì quá trình chuyển sang chế độ ngủ và lần đọc thứ hai không kiểm tra xem tệp có phải là nhị phân hay không.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Tìm nơi thông báo lỗi stderr được mã hóa:
git grep 'Binary file'
Dẫn chúng tôi đến /src/grep.c
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
Nếu các biến đó được đặt tên tốt, về cơ bản chúng tôi đã đi đến kết luận.
mã hóa_errorDefput
Grepping nhanh cho encoding_error_output
thấy rằng đường dẫn mã duy nhất có thể sửa đổi nó đi qua buf_has_encoding_errors
:
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
sau đó chỉ cần man mbrlen
.
nlines_first_null và nlines
Khởi tạo là:
intmax_t nlines_first_null = -1;
nlines = 0;
vì vậy khi một null được tìm thấy 0 <= nlines_first_null
trở thành sự thật.
TODO nlines_first_null < nlines
bao giờ có thể sai? Tôi đã lười biếng.
MỘT BỘ MÔ TẢ CHÍNH THỨC CUNG CẤP MỘT TIÊU CHUẨN CHO THIẾT KẾ HỆ ĐIỀU HÀNH, ĐẶC BIỆT LÀ CÁC MÔ TẢ TƯƠNG THÍCH VỚI UNIX
Không xác định tùy chọn nhị phân grep - tìm kiếm tệp cho mẫu | pubs.opengroup.org và GNU grep không ghi lại nó, vì vậy RTFS là cách duy nhất.
--null-data
có thể hữu ích nếuNUL
là dấu phân cách