GNU grep 2.24 RTFS
Schlussfolgerung: Nur 2 und 2 Fälle:
NUL
, z.B printf 'a\0' | grep 'a'
Codierungsfehler nach C99 mbrlen()
, zB:
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
da \x80
kann nicht das erste Byte eines UTF-8-Unicode-Punkts sein: UTF-8 - Beschreibung | en.wikipedia.org
Darüber hinaus, wie von Stéphane Chazelas erwähnt. Warum betrachtet grep eine Datei als binär? | Unter Unix und Linux Stack Exchange werden diese Überprüfungen nur bis zum ersten Puffer mit der Länge TODO durchgeführt.
Nur bis zum ersten Puffer gelesen
Wenn also ein NUL- oder Codierungsfehler in der Mitte einer sehr großen Datei auftritt, wird diese möglicherweise trotzdem abgegriffen.
Ich stelle mir das aus Performancegründen vor.
ZB: Dies druckt die Zeile:
printf '%10000000s\n\x80a' | grep 'a'
aber das tut nicht:
printf '%10s\n\x80a' | grep 'a'
Die tatsächliche Puffergröße hängt davon ab, wie die Datei gelesen wird. ZB vergleichen:
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
Mit dem sleep
wird die erste Zeile an grep übergeben, auch wenn sie nur 1 Byte lang ist, da der Prozess in den Ruhezustand wechselt und der zweite Lesevorgang nicht prüft, ob die Datei binär ist.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Finden Sie heraus, wo die stderr-Fehlermeldung codiert ist:
git grep 'Binary file'
Führt uns zu /src/grep.c
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
Wenn diese Variablen gut benannt wären, wären wir im Grunde genommen zu dem Schluss gekommen.
encoding_error_output
Das schnelle Greifen nach encoding_error_output
zeigt, dass der einzige Codepfad , der ihn ändern kann, durchläuft buf_has_encoding_errors
:
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
dann eben man mbrlen
.
nlines_first_null und nlines
Initialisiert als:
intmax_t nlines_first_null = -1;
nlines = 0;
Wenn also eine Null gefunden 0 <= nlines_first_null
wird , wird sie wahr.
TODO wann kann nlines_first_null < nlines
jemals falsch sein? Ich bin faul geworden.
POSIX
Definiert keine binären Optionen grep - Durchsucht eine Datei nach einem Muster | pubs.opengroup.org und GNU grep dokumentieren dies nicht, daher ist RTFS der einzige Weg.
--null-data
kann nützlich sein, wennNUL
das Trennzeichen ist.