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
ไม่สามารถเป็นไบต์แรกของจุด Unicode UTF-8 : UTF-8 - คำอธิบาย | en.wikipedia.org
นอกจากนี้ตามที่กล่าวโดยStéphane Chazelas grep ทำให้อะไรที่พิจารณาว่าไฟล์เป็น binary? | Unix & Linux Stack Exchange การตรวจสอบเหล่านั้นทำได้จนถึงการอ่านบัฟเฟอร์ครั้งแรกที่มีความยาวสิ่งที่ต้องทำ
อ่านบัฟเฟอร์แรกสุดเท่านั้น
ดังนั้นหากมีข้อผิดพลาด 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
, บรรทัดแรกจะถูกส่งผ่านไปยัง grep แม้ว่าจะมีความยาวเพียง 1 ไบต์เนื่องจากกระบวนการเข้าสู่โหมดสลีปและการอ่านครั้งที่สองไม่ได้ตรวจสอบว่าไฟล์เป็นไบนารีหรือไม่
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
ค้นหาตำแหน่งที่มีการเข้ารหัสข้อความแสดงข้อผิดพลาด:
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 อย่างรวดเร็วเพื่อ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;
ดังนั้นเมื่อพบค่าว่างจะ0 <= nlines_first_null
กลายเป็นจริง
สิ่งที่ต้องทำเมื่อnlines_first_null < nlines
เคยเป็นเท็จ? ฉันขี้เกียจ
POSIX
ไม่ได้กำหนดgrep options ของไบนารี- ค้นหาไฟล์เพื่อหา pattern | pubs.opengroup.orgและ grep GNU ไม่ได้จัดทำเอกสารดังนั้น RTFS จึงเป็นวิธีเดียวเท่านั้น
--null-data
อาจมีประโยชน์หากNUL
เป็นตัวคั่น