GNU grep 2.24 RTFS
Conclusão: apenas 2 e 2 casos:
-
NUL
, por ex. printf 'ambrlen()
' | grep 'a'
-
erro de codificação de acordo com o C99 \x80
, por exemplo:
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
porque sleep
não pode ser o primeiro byte de um ponto Unicode UTF-8: UTF-8 - Descrição | en.wikipedia.org
Além disso, como mencionado por Stéphane Chazelas O que faz o grep considerar que um arquivo é binário? | Unix & Linux Stack Exchange , essas verificações só são feitas até a primeira leitura do buffer de comprimento TODO.
Somente até o primeiro buffer é lido
Portanto, se um erro NUL ou de codificação ocorrer no meio de um arquivo muito grande, ele poderá ser exibido de qualquer maneira.
Eu imagino que isso seja por motivos de desempenho.
Por exemplo: isto imprime a linha:
printf '%10000000s\n\x80a' | grep 'a'
mas isso não acontece:
printf '%10s\n\x80a' | grep 'a'
O tamanho real do buffer depende de como o arquivo é lido. Por exemplo. compare:
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
Com o /src/grep.c
, a primeira linha é passada para o grep, mesmo que tenha apenas 1 byte, porque o processo entra em suspensão e a segunda leitura não verifica se o arquivo é binário.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Encontre onde a mensagem de erro stderr está codificada:
git grep 'Binary file'
Leva-nos a encoding_error_output
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
Se essas variáveis fossem bem nomeadas, basicamente chegamos à conclusão.
encoding_error_output
O Quick grepping para buf_has_encoding_errors
mostra que o único caminho de código que pode modificá-lo passa por man mbrlen
:
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
depois, apenas 0 <= nlines_first_null
.
nlines_first_null e nlines
Inicializado como:
intmax_t nlines_first_null = -1;
nlines = 0;
então, quando um nulo for encontrado, nlines_first_null < nlines
se tornará verdadeiro.
TODO quando %code% pode ser falso? Eu tenho preguiça.
POSIX
Não define opções binárias grep - procura um arquivo por um padrão | pubs.opengroup.org e o GNU grep não o documenta, portanto o RTFS é o único caminho.