web-dev-qa-db-ja.com

grep -Iで「バイナリファイルの一致」が表示されるのはなぜですか?

次の例では、grepの動作がおかしい:-Iオプションが指定されているため、manページによれば、grepにバイナリファイルを無視させる必要があります(--binary-files=without-matchと同様) )しかし、「バイナリファイルの一致」の出力がまだ表示されます。

$ cat <<'EOF' | uudecode > test-file
begin 664 /dev/stdout
M>`&5SLU*Q$`0!&#/>8J^"TM/=^8/1%2\>1`\>.^9Z=D-9!))9@7?WBB^@%"G
MHOBHO+8V=2!'-WU3A9PX%*8PBB:VGK@6)Y*HFAB(.2;.;$SQPX=LNG3(>2SH
MDJE!5;R+E9P21J::8U2+?@R>RK&7:[^L&[Q=]UD6>)$D?9<O_82[Y$\&S4_,
MP[G)-)_RVN[!6(S.>F0/M\B(P]$>5[O^%_$8+/(?,CSI+]%DD;/"^^,K3`OD
,6?8=GK6MPS?WDU!"
`
end
EOF
$ grep -I 8 test-file
Binary file test-file matches
$ grep --binary-files=without-match 8 test-file
Binary file test-file matches

どうやら、grepはファイルバイナリを考慮しますが、それでも結果を照合してレポートします。 -Iオプションで規定されているように、「バイナリファイル」が無視されないのはなぜですか?

私はGNU Ubuntu 18.04のgrep 3.1を使用しています。

5
Ruslan

grepマニュアル を見ると、これは(大胆なもの)が原因であると思われます。

typeが 'without-match'の場合、grepがnull入力バイナリデータを検出するとファイルの残りの部分が一致しないこと。これは、-Iオプションと同等です。

ただし、grepは他のデータもバイナリファイルを示すと見なします。

非テキストバイトはバイナリデータを示します。これらは、現在のロケールに対して正しくエンコードされていない出力バイト( 環境変数 を参照)、または-z--null-data)オプションが指定されていない場合のnull入力バイト(参照) その他のオプション )。

したがって、次の場合、メッセージは出力されません。

  • -I/--binary-files=without-matchオプションが指定されている
  • およびバイナリー性はnullバイトによるものです。

ただし、入力例ではそうではありません。サンプルファイルは、nullバイトがあるためではなく、現在のロケール(おそらく一部のUTFロケール)に適合しないため、バイナリとして扱われます。さもないと:

% LC_ALL=C grep 8 test-file  
x���J�@`�y��
dIf��(��P������6u G7}S��8�0�&���'����9&�lL�Çl�t�y,蒩AU����F��cT�~
                                                                 �ʱ�k��]�Yx�$}�/����O�O�ù�4�����X��zd�Ȉ��W���,�2<�/�d�����+L
                                                                                                                            �Y�����7��PB

ファイルにnullバイトを追加すると、grepが失敗します。

% printf '\0' >> test-file
% grep -I 8 test-file    
% echo $?
1
8
muru