私は他のファイルの中に3つの名前付きパイプ(FIFO、FIFO1、およびFIFO11)を含むディレクトリを持っています。私が次のようなことをしようとすると
grep mypattern *
このディレクトリでは、grepは名前付きパイプに永久にかかっているため、これを除外する必要があります。意外に、
grep --exclude='FIF*' mypattern *
問題は解決されませんでした。 grepはまだ永遠に中断されます。しかし、
grep -r --exclude='FIF*' mypattern .
する停止の問題を解決します(すべてのサブディレクトリを検索するための望ましくない副作用があるにもかかわらず)。
いくつかのテストを試してみると、grep --exclude ='FIF*' mypattern *
FIFOなどが名前付きパイプではなく通常のファイルである場合、期待どおりに動作することがわかりました。
質問:
- 通常のファイルの場合、どちらの場合も名前付きパイプをスキップし、再帰的な
grep
場合は名前付きパイプをスキップしますが、非再帰的な場合はスキップしないのはなぜですか?--excludes
--excluded
- どのような場合でも、これらのファイルをスキップする除外形式を指定する他の方法はありますか?
- 私が望むことを達成するためのより良い方法はありますか? (編集:私は
--devices=skip
grepでフラグを見つけたので、これはその部分への答えです...しかし、まだ質問の最初の2つの部分が気になります。)
ベストアンサー1
grep
まだそうだ開いている正規表現でファイルをスキップするように指示しても、次のようになります。
$ ll
total 4.0K
p-w--w---- 1 user user 0 Feb 7 16:44 pip-fifo
--w--w---- 1 user user 4 Feb 7 16:44 pip-file
lrwxrwxrwx 1 user user 4 Feb 7 16:44 pip-link -> file
(注:これらのいずれにも読み取り権限がありません。)
$ strace -e openat grep foo --exclude='pip*' pip-file pip-link pip-fifo
openat(AT_FDCWD, "pip-file", O_RDONLY|O_NOCTTY) = -1 EACCES (Permission denied)
grep: pip-file: Permission denied
openat(AT_FDCWD, "pip-link", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
grep: pip-link: No such file or directory
openat(AT_FDCWD, "pip-fifo", O_RDONLY|O_NOCTTY) = -1 EACCES (Permission denied)
grep: pip-fifo: Permission denied
+++ exited with 2 +++
読み取り権限を付与して除外すると、開いた後に読み込もうとしないようです。
$ strace -e openat grep foo --exclude='pip*' pip-file pip-link pip-fifo
openat(AT_FDCWD, "pip-file", O_RDONLY|O_NOCTTY) = 3
openat(AT_FDCWD, "pip-link", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
grep: pip-link: No such file or directory
openat(AT_FDCWD, "pip-fifo", O_RDONLY|O_NOCTTY^Cstrace: Process 31058 detached
<detached ...>
$ strace -e openat,read grep foo --exclude='pip*' pip-file
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\25\0\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\r\0\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260`\0\0\0\0\0\0"..., 832) = 832
openat(AT_FDCWD, "pip-file", O_RDONLY|O_NOCTTY) = 3
+++ exited with 1 +++
$ strace -e openat,read grep foo --exclude='pipe*' pip-file
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\25\0\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\r\0\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260`\0\0\0\0\0\0"..., 832) = 832
openat(AT_FDCWD, "pip-file", O_RDONLY|O_NOCTTY) = 3
read(3, "foo\n", 32768) = 4
foo
read(3, "", 32768) = 0
+++ exited with 0 +++
~からopenat
呼び出しは使用されず、O_NONBLOCK
開始部分自体が中断され、grepは読み取りから除外された部分に到達できません。
ソースコードを見てみると、プロセスは次のようになります。
- 再帰的でない場合は、次を呼び出します。
grep_command_line_arg
すべてのファイルに。 - これは…
grepfile
標準入力でない場合。 grepfile
着信電話grepdesc
後ろにファイルを開きます。grepdesc
調査するこのファイルを除外。
繰り返すとき:
grepdirent
除外ファイルの確認呼び出す前にgrepfile
失敗はopenat
発生しません。