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
Кроме того, как уже упоминал Стефан Шазелас, что заставляет grep считать файл двоичным? | Unix и Linux Stack Exchange , эти проверки выполняются только до первого чтения буфера длины 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
первой строки передается grep, даже если длина ее составляет всего 1 байт, потому что процесс переходит в спящий режим, а второе чтение не проверяет, является ли файл двоичным.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Найдите, где закодировано сообщение об ошибке stderr:
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
это разделитель.