GNU grep 2.24 RTFS
Conclusione: solo 2 e 2 casi:
NUL
, per esempio printf 'a\0' | grep 'a'
errore di codifica secondo C99 mbrlen()
, ad es .:
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
perché \x80
non può essere il primo byte di un punto Unicode UTF-8 : UTF-8 - Descrizione | en.wikipedia.org
Inoltre, come indicato da Stéphane Chazelas Cosa rende grep un file binario? | Unix & Linux Stack Exchange , questi controlli vengono eseguiti solo fino alla prima lettura del buffer di lunghezza TODO.
Solo fino al primo buffer letto
Quindi, se si verifica un errore NUL o di codifica nel mezzo di un file di dimensioni molto grandi, potrebbe comunque essere grepped.
Immagino che questo sia per motivi di prestazioni.
Ad esempio: questo stampa la riga:
printf '%10000000s\n\x80a' | grep 'a'
ma questo non:
printf '%10s\n\x80a' | grep 'a'
La dimensione effettiva del buffer dipende dalla modalità di lettura del file. Ad esempio confrontare:
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
Con sleep
, la prima riga viene passata a grep anche se è lunga solo 1 byte perché il processo va in sospensione e la seconda lettura non controlla se il file è binario.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Trova dove è codificato il messaggio di errore stderr:
git grep 'Binary file'
Ci porta a /src/grep.c
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
Se quelle variabili fossero ben denominate, in pratica arriveremmo alla conclusione.
encoding_error_output
Quick grepping per encoding_error_output
mostra che l'unico percorso di codice che può modificarlo passa attraverso buf_has_encoding_errors
:
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
quindi solo man mbrlen
.
nlines_first_null e nlines
Inizializzato come:
intmax_t nlines_first_null = -1;
nlines = 0;
quindi quando viene trovato un null 0 <= nlines_first_null
diventa vero.
TODO quando nlines_first_null < nlines
mai può essere falso? Sono diventato pigro.
POSIX
Non definisce le opzioni binarie grep - cerca un modello per un modello | pubs.opengroup.org e GNU grep non lo documenta, quindi RTFS è l'unico modo.
--null-data
può essere utile seNUL
è il delimitatore.