![grep --exclude 옵션이 명명된 파이프를 항상 건너뛰지는 않습니다.](https://linux55.com/image/147767/grep%20--exclude%20%EC%98%B5%EC%85%98%EC%9D%B4%20%EB%AA%85%EB%AA%85%EB%90%9C%20%ED%8C%8C%EC%9D%B4%ED%94%84%EB%A5%BC%20%ED%95%AD%EC%83%81%20%EA%B1%B4%EB%84%88%EB%9B%B0%EC%A7%80%EB%8A%94%20%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
나는 다른 파일들 중에서 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에서 플래그를 발견했으므로 이것이 해당 부분에 대한 답변입니다... 하지만 여전히 질문의 처음 두 부분이 궁금합니다.)
답변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
발생하지 않습니다.
답변2
"찾기"와 결합해 보는 것은 어떨까요? 파일만 포함된 목록을 가져와서 입력합니다.
find /path/to/dir -type f -exec grep pattern {} \;