찾기 및 심볼릭 링크

찾기 및 심볼릭 링크

명령 사용법에 대한 더 나은 아이디어를 얻기 위해 find에 대한 문서를 찾아보았습니다.

내가 읽고 있는 부분은 이렇게 말한다.

GNU find는 두 가지 방법 중 하나로 심볼릭 링크를 처리합니다. 먼저 링크를 역참조할 수 있습니다. 즉, 심볼릭 링크를 발견하면 링크가 가리키는 파일을 확인하여 지정한 기준을 충족하는지 확인합니다. 둘째, 실제 링크를 찾고 있는 경우 링크 자체를 확인할 수 있습니다. find 명령을 사용하여 검색한 디렉토리 계층 구조 내에 있는 파일을 기호 링크가 가리키는 경우 두 가지 방법 사이에 큰 차이가 없을 수도 있습니다.

기본적으로 find는 심볼릭 링크를 발견하면 그 자체를 확인합니다(그리고 나중에 링크된 파일을 발견하면 링크도 확인합니다).

내가 이해하는 바에 따르면 다음과 같은 작업을 수행하면:

find -L -iname "*foo*"

이는 현재 디렉토리를 재귀적으로 검색하고, 심볼릭 링크가 발견되면 원본 파일에 대한 링크를 따라 검색합니다. 원본 파일 이름이 패턴인 경우 *foo*이전 링크가 보고됩니다.

그러나 이는 사실이 아닌 것 같습니다. 나는 가지고있다

main-file
sl-file -> main-file

위 명령을 실행하면 find -L -iname "*main*"보고됩니다.

./main-file

나는 그것을 기대한다

./main-file # because it matches the criterion
./sl-file   # because the file points to matches the criterion

즉, 다른 테스트를 사용하면 -type예상한 대로 작동합니다. 내가 이것을 가지고 있다고 가정 해 봅시다 :

main-file
dir/sl-file -> ../main-file

이것을 실행

find dir -type f

아무것도 반환하지 않습니다. 하지만 이것은

find -L dir -type f

보고서 dir/sl-file.

무엇을 제공합니까?

나는 이미 경험했다이 게시물이는 파일 이름이 파일 속성이 아님을 의미합니다. 이건 정말 이해할 수 없는 일이에요.

답변1

Gnu find문서는 용어상 유사하지 않습니다.POSIX 하나. 후자는 요점을 설명하며 나는 그것을 언급할 것이다. 정의되지 않았 -iname으므로 이에 초점을 맞추겠습니다 . 대소문자를 구분하지 않고 유사하게 설계되었다고 -name생각합니다 . 그러므로 나는 그 모든 속성이 적용 가능한 사례와도 독립적이기를 원합니다.-iname-name-name-iname

POSIX 문서의 관련 부분은 다음과 같습니다.

find [-H|-L] path... [operand_expression...]
이 유틸리티는 […]으로 지정된 각 파일에서 디렉터리 계층 구조를 반복적으로 내려야 find합니다 . 후행 <슬래시> 문자를 포함하여 pathpath피연산자는 제공된 대로 평가됩니다. 계층 구조에서 발견된 다른 파일에 대한 모든 경로 이름은 현재 경로 피연산자(현재 경로 피연산자가 1로 끝나지 않는 경우 <슬래시>)로 평가됩니다. 경로 피연산자를 기준으로 파일 이름을 연결합니다. 반대 부분에는 점 또는 점-점 구성 요소가 포함되어서는 안 되며, 후행 <슬래시> 문자도 포함되어서는 안 되며, 경로 이름 구성 요소 사이에는 단일 <슬래시> 문자만 포함되어야 합니다.

-name pattern
현재 경로 이름의 기본 이름이 패턴 일치 표기법을 사용하여 일치하는 경우 pattern기본 용어는 true로 평가되어야 합니다 [...]

-print
[...] 현재 경로 이름이 표준 출력에 기록됩니다.

그리고정의:

basename
하나 이상의 파일 이름을 포함하는 경로 이름의 경우: 경로 이름의 마지막 또는 유일한 파일 이름입니다. […]

파일 이름
파일 이름을 지정하는 데 사용되는 일련의 바이트 [...]입니다. 이름을 구성하는 바이트에는 <NUL> 또는 <slash> 문자가 포함될 수 없습니다. [...] 파일 이름은 "경로 이름 구성 요소"라고도 합니다. […]

경로명
파일을 식별하는 데 사용되는 문자열입니다. [...] 선택적인 시작 <슬래시> 문자가 있고 그 뒤에는 <슬래시> 문자로 구분된 0개 이상의 파일 이름이 옵니다.

따라서 -name현재 경로 이름의 최종 파일 이름에 관심이 있습니다. 현재 경로 이름은 현재 파일을 식별하는 문자열입니다. 누구에 의해 사용됩니까? 이 경우 find경로 이름은 개념적으로 파일 시스템의 이름과 아무 관련이 없을 수 있습니다. find특정 문자열이 파일을 식별하는 데 사용되는 경우 해당 문자열을 "경로 이름"이라고 하며 -name사용됩니다.

호출 find . -print또는 find -L . -print. 이 특정 호출에 사용된 모든 경로 이름이 표시됩니다 find. .-name-name


main-file및 를 사용한 예에서 sl-file명령은 입니다 find -L -iname "*main*". -print마지막으로 당신이 관찰한 결과는 다음과 같습니다 -print.

./main-file # because it matches the criterion
./sl-file   # because the file points to matches the criterion

하지만 그렇다면 이는 and -print가 주어졌음을 의미하므로 이것이 정확한 경로 이름이고 따라서 및 는 처리할 해당 기본 이름 (또는) 입니다../main-file./sl-filemain-filesl-file-name-iname

이는 부적절합니다. 이러한 기본 이름 중 하나만 사용하는 패턴( )과 일치합니다 *main*. 그렇기 때문에 결과는 하나만 얻을 수 있습니다. -name "*main*"(또는 )을 지정 -iname "*main*"하고 발생을 예상하는 것은 일치를 ./sl-file예상하는 것과 같습니다 .sl-file*main*

이것은 만들 것이다일부그 느낌은 ./main-file두 번 일어날 것으로 예상됩니다. 단, 심볼릭 링크로 인해 find두 번째 경로 이름이 에서 로 변경 ./sl-file됩니다 ./main-file. 그러면 두 경로 이름이 일치 *main*하고 둘 다 로 인쇄됩니다 ./main-file. 이런 일은 발생하지 않습니다.

이를 원할 경우 에 심볼릭 링크를 bar가리키고 배치하는 것을 고려하십시오 . 우리는 디렉토리 에 있습니다 . 무엇을 인쇄 해야 합니까 ( 제외 )? 이 경로 이름 이 테스트를 통과하기를 원하는 것 같으 므로 기본 이름은 이어야 합니다 . 반면에 규칙에 따라 경로 이름은 ( 제공된 경로와 마찬가지로)로 시작해야 하며 점 구성 요소를 포함해서는 안 됩니다. 사용할 수 있는 정상적이고 의미 있는 경로 이름은 없습니다. 무엇을 해야 할까요? 다행히 이 경우 도구는 경로 이름인 .을 인쇄하며 문자열로 ./etc/fstab/tmp/foo/foofind -L ..-name fstabfstab./../barfstab


심볼릭 링크를 사용하지 않지만 -name작동 방식을 보여주는 몇 가지 예:

  1. cd /etc && find . -name . 2>/dev/null

    .이는 "실제"(파일 시스템의 특정) 이름이 이라는 사실에도 불구하고 etc어떤 경우에는 디렉토리가 존재할 수 있지만 하위 디렉토리를 찾을 수는 없습니다 ..

  2. cd /etc && find . -name etc 2>/dev/null

    etc찾을 수도 없고 사용할 수도 없습니다 ..

  3. 빈 FAT32 파일 시스템을 생성하고 이를 cd마운트 지점에 마운트합니다. 파일 시스템은 대소문자를 구분하지 않으며 Linux는 이를 알고 있습니다. a파일 시스템에 이름이 지정된 파일을 생성합니다 . 다음과 같이 실험해 보세요.

    • $ find .
      .
      ./a

      a이 경우 도구는 특정 시점에 파일 시스템에서 이를 가져와야 합니다.

    • $ find a
      a
      $ find A
      A

      이 경우 도구는 명령줄 인수를 사용 a하거나 가져옵니다. A파일 시스템은 그러한 파일이 존재하는지 확인만 합니다. 파일 시스템(및 운영 체제)은 이 특정 파일이 a또는 A.

    • $ find a -name A
      $ find A -name a

      아무것도 없어! 이는 -name파일 시스템이 파일에 대해 무엇을 알고 있는지 상관하지 않는다는 것을 나타냅니다. 사용된 경로 이름만 find중요합니다.

      귀하의 예와 비슷한 점은 -iname파일 시스템이 심볼릭 링크와 그 대상에 대해 무엇을 알고 있는지 상관하지 않는다는 것입니다. 사용된 경로 이름만 find중요합니다.


무슨 일이 일어나고 있는지 명확히 하기 위해 다음 디렉터리 구조를 사용하여 예제로 돌아가겠습니다.

.
├── main-file
└── sl-file -> main-file

find . -print또는 find -L . -print인쇄:

.
./main-file
./sl-file

이는 경로 이름입니다. find세 가지를 식별하는 데 사용됨문서(디렉토리는 또한문서). 문자열은 .명령에서 나오며, 나머지 두 개는 .확인(문자열이 아닌 파일을 의미함), 디렉토리 유형 이해, 하위 항목 결정(지원되는 경우 일반적으로 고려됨 -prune) -maxdepth, 내용 나열을 통해 작성 됩니다 main-file.sl-file

이 문자열은 /.sl-file식별하는 파일에 대해 작업이 수행되기 전에 구성됩니다. 이 문자열은 파일에 대한 작업을 수행하는 데 find필요합니다 .

그러나 파일에 대해 아무 작업도 수행하지 않으며 해당 데이터나 메타데이터도 필요하지 않습니다 -name. -print그들은 경로 이름을 사용합니다..

경로 이름을 평가할 때 -name "*main*"해당 파일이나 전체 파일 시스템은 전혀 관련이 없습니다. 관련된 유일한 것은 경로 이름입니다.;더 구체적으로 말하면 마지막 구성 요소인 기본 이름도 다음과 같습니다..

특정 경로 이름에 대해 해당 경로 -name를 사용했는지 -L, 파일이 처음에 심볼릭 링크인지, 가리키는 위치인지, 손상되지 않았는지 여부는 중요하지 않습니다. 그것은 알려진 것과 관련이 있다.

반면에 파일 시스템 쿼리 와 유사 -type하거나 쿼리가 필요한 테스트는-mtime문서경로 이름으로 식별됩니다. 문자열로는 충분하지 않습니다. 심볼릭 링크인 경우 -L심볼릭 링크의 대상을 쿼리할지 아니면 심볼릭 링크 자체를 쿼리할지 결정합니다. 그러나 -print관련된 경우에는 쿼리 내용에 관계없이 경로 이름을 인쇄합니다.

다시 말해서:

  • 아니요-L

    • ./main-file 식별하다./main-file 문서유형f
    • ./sl-file 식별하다./sl-file 문서유형l
  • 그리고-L

    • ./main-file 식별하다./main-file 문서유형f
    • ./sl-file 아직 확인됨./main-file 문서유형f

그런 다음 경로 이름(문자열)에 적용되는 테스트 또는 작업과 파일에 적용되는 테스트 또는 작업을 기록해야 합니다.

-name-print경로 이름을 사용하므로 유무 find . -name "*main*"에 관계없이 -L인쇄됩니다.

./main-file

-type파일에서 작동하므로 find . -type f경로 이름이 인쇄됩니다.

./main-file

두 경로 이름을 모두 인쇄 합니다 find -L . -type f.

./main-file
./sl-file

관련 정보