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
इसके अलावा, जैसा कि स्टीफन चेज़ेलस ने उल्लेख किया है कि क्या 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 बाइट लंबी होती है तो भी जीआरपी को पास कर दिया जाता है क्योंकि यह प्रक्रिया सो जाती है, और दूसरी रीड की जांच नहीं होती है कि फाइल बाइनरी है या नहीं।
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
त्वरित ग्रेपिंग से 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
जाता है तो वह सच हो जाता है।
TODO कब nlines_first_null < nlines
कभी झूठ हो सकता है? मैं आलसी हो गया।
POSIX
द्विआधारी विकल्प को परिभाषित नहीं करता है grep - एक पैटर्न के लिए एक फ़ाइल खोजें pubs.opengroup.org , और GNU grep इसे प्रलेखित नहीं करते हैं, इसलिए RTFS एकमात्र तरीका है।
--null-data
यदिNUL
सीमांकक उपयोगी है।