man
このオプションのページの説明grep
は次のとおりです-d ACTION
。
入力ファイルがディレクトリの場合は、
ACTION
それを処理するために使用します。デフォルトでは、ACTION
isはread
通常のファイルのようにディレクトリを読み込みます。 [...]
bar
直感的に、これはディレクトリが(pingのために)私が入力したときに表示されるものとgrep
ほぼ同じ内容を含むテキストファイルと同じように扱われることを意味すると予想されます。つまり、およそ(変更内容によって異なる)一種の上部および下部に説明情報および/またはメタデータを表示する。vim
vim foo
"============================================================================
" Netrw Directory Listing (netrw v156)
" /home/chris-henry/bar
" Sorted by name
" Sort sequence: [\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:special
" ==============================================================================
../
./
foobar/
baz/
qux
この場合、grep -H foo bar
出力が生成されます。
bar: foobar/
代わりにメッセージを提供してくださいgrep: bar: Is a directory
。なぜこれですか?直感的な結果を得る(かなり単純な)方法はありますか(この単純な検索だけでなく、テキストファイル、バイナリファイル、およびディレクトリの一部または全部と一致する場所などのgrep foo *
検索も可能です)。*
到着予定時刻(2021-07-22):許可された回答で提案され、コメントで確認されたように、それ自体は実際に私が予想したものと正確に一致します。通常のファイルと同様に、ファイル記述子を使用して()grep foo bar
へのシステムコールを呼び出します。read
この時点で内容を入力するのではなく、エラーコードが返され、適切な診断メッセージが印刷された後、次のファイルでプロセスが続行されます。これはエラーコード(時にはそうではありません)を返し、通常のファイルになるのと同じです。 。ssize_t read(int fd, void *buf, size_t count)
bar
bar
read
*buf
bar
EISDIR
grep
read
EINTR
EINVAL
bar
私の期待と現実の違いは、Linuxバージョンの動作から来ています(コメントによると、他のほとんどの最新バージョン)read
。つまり、fd
ディレクトリが参照されると自動的に返されますEISDIR
。
到着予定時刻2(2021-07-23):この質問に対する主な動機は、説明された直感的な動作を得る必要がある緊急の必要性ではありません(私はこれが潜在的な二次的な利点として興味がありますが)。動機は、grep
出力に基づいて(GNU)がマニュアルページの主張と矛盾するように見えるように動作する理由を理解することです。
答えはgrep
、実際にはマニュアルページに記載されているように実行しているということです。ただし、システムコールの(一般的な)動作が変更されたread
場合結果ほとんどの最新システムでは、grep
(最新の実装の動作に慣れていない状態で)マニュアルページを読むだけでread
推論できるものとはかなり異なります。
全体的に私はこのことをしないほうがよいでしょうがread
、この行動が次のような関係があるかどうか疑わしいです。それマンページ。現在の状況を考慮すると、マニュアルページに1〜2行を追加したかったのですが、grep
そうではありません。間違った実際、それは誤解を招くだけです。
答え1
ディレクトリにはテキスト形式の本質的な表現はありません。多くのUnixバリアントでは、プログラムが通常のファイルのようにディレクトリからデータを読み取ることができますが、コンテンツ形式はファイルシステムによって異なるため、これはほとんど役に立ちません。 Linuxを含むいくつかの最新のUnixバリアントプログラムがディレクトリを通常のファイルであるかのように読み取ることを完全に防ぎます。。
たとえば、次はFreeBSDで何が起こるかです(以前のバージョンではまだ許可されています。FreeBSD 13以降はデフォルトで無効になっています)。次のディレクトリは次のとおりですbar
。
$ grep -H foo bar
Binary file bar matches
$ grep -H --text foo bar
bar:�"!
.�
..�"!foobar�"!
baz�"!qux
はい、ディレクトリ表現に存在するかどうかはわかりますが、foo
ファイル名の一部であるかどうかはわかりません。たとえば(まだFreeBSDシステムにあります):
$ rmdir bar/foobar
$ grep -H --text foo bar
bar:�"!
..�"!foobar�"!
baz�"!foo
ディレクトリを削除すると、ファイルシステムからディレクトリが削除されますが、ディレクトリをエンコードするディスク構造から削除されたエントリの名前は消去されません。
Vimにディレクトリを開くように要求すると、Vimはディレクトリをナビゲートし(たとえば、readdir
一般的な機能を使用するのではなく特殊なシステム機能を使用してread
)、結果を見やすく表示します。
Grepは同様のものを実装できますが、grepのサイズに比べて多くの作業が必要であり、ファイルの内容を検索するgrepの重要な目的から逸脱し、実装が満足のいく妥協でなければなりません。多くの人。ディレクトリのテキスト表現にはファイル名または一部のメタデータのみが含まれていますか(grep "Jul 20" bar
7月20日に変更されたファイルが見つからないのですか)。項目を区切る方法(ファイル名に改行を含めることができるため、改行で区切られている場合は表現があいまいです。ヌルバイトで区切られている場合、出力は役に立ちますgrep --null-data
)。
シェルワイルドカードfind
とlocate
。