Solaris의 find 명령에서 전체 디렉토리 경로 목록을 제외하는 방법

Solaris의 find 명령에서 전체 디렉토리 경로 목록을 제외하는 방법

(스택 오버플로에서 복사됨:https://stackoverflow.com/questions/7854975/how-to-exclude-a-list-of-full-directory-paths-in-find-command-on-solaris)

Solaris에서 소유되지 않은 파일과 디렉터리를 찾기 위해 스크립트를 사용해야 하는 매우 구체적인 요구 사항이 있으며, 수천 개의 소유되지 않은 파일이 포함될 수 있으므로 전체 디렉터리 경로를 조회에서 제외할 수 있어야 합니다(파일이 호스팅되기 때문에 이는 정상입니다). 다른 파일) 서버). 서버가 정지되므로(CPU가 장기간 99%로 급증) 이러한 디렉토리에서 찾기 검색을 수행하고 싶지도 않습니다. 따라서 egrep에서 찾기 결과를 파이핑하여 이러한 디렉토리를 필터링하는 것은 옵션이 아닙니다.

여러 디렉터리 중 하나를 이름으로 제외하기 위해 이 작업을 수행할 수 있다는 것을 알고 있습니다.

find / -mount -local \( -type d -a \( -name dir1 -o -name dir2 -o dir3 \) \) -prune -o \( -nouser -o -nogroup \) -print

그러나 이는 모든 디렉터리의 디렉터리 구조 어디에서나 dir1 및 dir2와 일치합니다.아니요내가 원하는 것.

나는 find가 다음 디렉토리에서 검색하는 것을 방지할 수 있기를 원합니다(예를 들어):

/opt/dir1
/opt/dir2
/var/dir3/dir4

나는 여전히 다음 위치에서 소유되지 않은 파일과 디렉터리를 찾고 싶습니다.

/opt/somedir/dir1
/var/dir2
/home/user1/dir1

-name 매개변수에 정규식을 사용해 보았지만 find는 찾은 기본 이름과 "name"만 일치하므로 경로를 지정할 수 없습니다. 불행히도 Solaris의 조회는 -wholename 또는 -path와 같은 GNU 조회 옵션을 지원하지 않으므로 약간 문제가 있습니다.

내 목표는 다음 구문을 사용하는 스크립트를 만드는 것입니다.

script.sh "/path/to/dir1,/path/to/dir2,/path/to/dir3"

find 및 표준 sh 스크립트(/bin/sh)를 사용하여 Solaris(5.8 이상)에서 이 작업을 어떻게 수행합니까?

답변1

전체 경로로 파일을 일치시킬 수 없습니다.솔라리스find, 그러나 inode별로 파일을 일치시킬 수 있습니다. 따라서 ls -i정리할 inode 목록 생성을 사용한 다음 를 호출하십시오 find. 이는 정리하려는 디렉토리가 너무 많지 않아 명령줄 길이 제한을 초과한다고 가정합니다.

inode_matches=$(ls -bdi /opt/dir1 /opt/dir2 /var/dir3/dir4 |
                sed -e 's/ *\([0-9][0-9]*\) .*/-inum \1 -o/')
find / -xdev \( $inode_matches -nouser -o -nogroup \) -prune -o -print

또 다른 접근 방식은 Perl 또는 Python 스크립트를 사용하여 자체 디렉터리 탐색을 수행하는 것입니다. Perl에는 모듈 find2perl사용을 시작하는 데 도움이 되는 스크립트가 함께 제공됩니다 File::Find. Python에서는 모듈 walk의 함수를 참조하세요 os.path.

답변2

find 구현은 테스트를 지원하지 않으므로 ( 전체 경로 이름으로 확장해야 함) -path을 사용하여 모의할 수 있습니다 .-exec test "{}" = "/path/to/exclude" \; -prune{}

test불행하게도 프로그램은 매 실행마다 실행되므로 "순수한" 조회보다 시간이 더 걸립니다 . 따라서 가능한 경우 테스트를 최적화하십시오. 예를 들어 다음 두 가지 중 어느 것이 더 빠르게 실행되는지 확인하십시오.

 -exec test "{}" = "/dev" \; -o -exec test "{}" = "/proc" \; -o -exec test "{}" = "/tmp/test" \;

또는

 -exec test "{}" = "/dev" -o "{}" = "/proc" -o "{}" = "/tmp/test" \;

test프로그램이 한 번만 실행되기 때문에 후자가 전체적으로 더 빨라야 한다고 생각합니다 .

-a참고: 은(는) 필요하지 않으며 기본적으로 암시됩니다. -print결국 같은 일이 일어났습니다.

관련 정보