깨진 심볼릭 링크를 어떻게 찾을 수 있습니까


282

전혀 지적하지 않은 모든 심볼릭 링크를 찾는 방법이 있습니까?

find ./ -type l

모든 심볼릭 링크를 제공하지만 어딘가로 이동하는 링크와 그렇지 않은 링크를 구분하지 않습니다.

나는 현재하고있다 :

find ./ -type l -exec file {} \; |grep broken

그러나 대체 솔루션이 무엇인지 궁금합니다.

답변:


351

나는 작업 에 사용 하지 말 것을 강력히 권합니다 find -L(설명은 아래 참조). 이를 수행하는 다른 방법은 다음과 같습니다.

  • "순수한 find"방법 을 사용하려면 다음과 같이 표시되어야합니다.

    find . -xtype l
    

    ( xtype역 참조 링크에서 수행 된 테스트입니다.) 일부 버전에서는이 기능을 사용할 수 없습니다 find. 그러나 다른 옵션도 있습니다.

  • 명령 test -e내에서 exec 를 실행할 수도 있습니다 find.

    find . -type l ! -exec test -e {} \; -print
    
  • 심지어 어떤 grep트릭 조차 ( )보다 좋을 수도 있지만 더 안전 할 수도 find -L있지만 질문에 제시된 것과 정확히 같지는 않습니다 (파일 이름을 포함한 전체 출력 라인에서 greps).

     find . -type l -exec sh -c 'file -b "$1" | grep -q ^broken' sh {} \; -print
    

find -L인용 트릭 솔로로 에서 commandlinefu는 좋은 해키 보이지만, 그것은 하나 개의 아주가 위험한 함정을 : 모든 심볼릭 링크가 따른다. 아래에 제시된 내용의 디렉토리를 고려하십시오.

$ ls -l
total 0
lrwxrwxrwx 1 michal users  6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users  6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/

find -L . -type l해당 디렉토리에서 실행하면 모든 항목 /usr/share/도 검색되며 실제로 시간이 오래 걸릴 수 있습니다 1 . A의 find"외부 링크에 면역"입니다 명령을 사용하지 마십시오-L .


1 이것은 약간의 불편 함처럼 보일 수 있습니다 (명령은 "모든 것을 순회하는 데 시간이 오래 걸립니다" /usr/share). 그러나 더 심각한 결과를 초래할 수 있습니다. 예를 들어, chroot 환경을 고려하십시오. 기본 파일 시스템의 일부 하위 디렉토리에 존재할 수 있으며 절대 위치에 대한 심볼릭 링크를 포함 할 수 있습니다. 이 링크는 "외부"시스템에서 끊어진 것처럼 보일 수 있습니다. chroot에 들어간 후에는 적절한 위치 만 가리 키기 때문입니다. 또한 일부 부트 로더 /boot는 부팅 파티션이로 마운트되었을 때 초기 부팅 단계에서만 의미가있는 심볼릭 링크를 사용 했음을 상기합니다 /.

따라서 find -L명령을 사용하여 무해한 디렉토리에서 깨진 심볼릭 링크를 찾아서 삭제하면 시스템이 손상 될 수도 있습니다.


11
비 링크에서 작동하기 -type l때문에 중복 적이 라고 생각 합니다. 그래서 아마 당신이 필요로하는 모두이다. 이 접근법에 감사드립니다. -xtype l-type lfind -xtype l
quornian

3
이러한 솔루션은 모든 파일 시스템 유형에서 작동하지는 않습니다. 예를 들어 /proc/XXX/exe링크가 끊어 졌는지 확인하는 데는 작동하지 않습니다 . 이를 위해을 사용하십시오 test -e "$(readlink /proc/XXX/exe)".
qwertzguy

2
@Flimm find . -xtype l은 "(궁극적 인) 대상 파일이 symlink 인 모든 symlink를 찾습니다"를 의미합니다. 그러나 심볼릭 링크의 궁극적 인 대상은 심볼릭 링크가 될 수 없습니다. 그렇지 않으면 링크를 계속 따라갈 수 있으며 궁극적 인 대상이 아닙니다. 그러한 심볼릭 링크가 없기 때문에 심볼릭 링크를 다른 것으로 정의 할 수 있습니다.
weakish

2
@ JoóÁdám "손상된 경우에만 심볼릭 링크가 될 수 있습니다". 오버로드하는 대신 "부러진 심볼릭 링크"또는 "존재하지 않은 파일"을 개별 유형으로 지정하면 l혼란이 줄어 듭니다.
12

3
마지막 경고는 유용하지만 이것은 -L해킹 에는 적용되지 않지만 일반적으로 깨진 심볼릭 링크를 (맹목적으로) 제거하는 데 적용됩니다 .
Alois Mahdal


32

rozcietrzewiacz가 이미 언급 find -L했듯이 검색을 심볼릭 링크 디렉토리로 확장하면 예기치 않은 결과가 발생할 수 있으므로 최적의 접근 방식은 아닙니다. 아직 언급하지 않은 것은

find /path/to/search -xtype l

보다 간결하고 논리적으로 동일한 명령입니다

find /path/to/search -type l -xtype l

지금까지 제시된 솔루션 중 어느 것도 순환 심 링크를 감지하지 못하는데, 이는 또 다른 유형의 파손입니다. 이 질문 은 이식성을 다루고 있습니다. 요약하면, 순환 링크를 포함하여 깨진 기호 링크를 찾는 이식 가능한 방법은 다음과 같습니다.

find /path/to/search -type l -exec test ! -e {} \; -print

자세한 내용은 이 질문 또는 ynform.org를 참조하십시오 . 물론이 모든 것의 확실한 소스는 findutils documentaton 입니다.


1
짧고 간결 find -L하며 순환 링크뿐만 아니라 함정도 다루고 있습니다. 한
Flimm

좋은. 마지막은 MacOSX에서도 작동하지만 @rozcietrzewiacz의 답변은 그렇지 않았습니다.
neu242

1
@ neu242 -xtypePOSIX에 지정되지 않았기 때문에 find(1)macOS 에서 -type보았지만 실제로는 그렇지 않습니다 -xtype .
Pryftan

7

-L명령에 플래그를 추가 하면 grep을 제거 할 수 있다고 생각 합니다.

$ find -L . -type l

http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks

남자에게서 :

 -L      Cause the file information and file type (see stat(2)) returned 
         for each symbolic link to be those of the file referenced by the
         link, not the link itself. If the referenced file does not exist,
         the file information and type will be for the link itself.

19
처음에 나는 이것을 높이 평가했지만 그것이 얼마나 위험 한지 깨달았습니다 . 당신이 그것을 사용하기 전에, 제발 내 대답에 봐 !
rozcietrzewiacz

6

링크가 끊어 졌는지 주기적인지에 관계없이 다른 동작이 필요한 경우 find와 함께 % Y를 사용할 수도 있습니다.

$ touch a
$ ln -s a b  # link to existing target
$ ln -s c d  # link to non-existing target
$ ln -s e e  # link to itself
$ find . -type l -exec test ! -e {} \; -printf '%Y %p\n' \
   | while read type link; do
         case "$type" in
         N) echo "do something with broken link $link" ;;
         L) echo "do something with cyclic link $link" ;;
         esac
      done
do something with broken link ./d
do something with cyclic link ./e

이 예는 이 게시물 에서 복사되었습니다 (사이트가 삭제됨) .

참고


find명령을 지원하지 않는 사람들을위한 또 다른 속기 xtype는 다음에서 파생 될 수 있습니다 find . type l -printf "%Y %p\n" | grep -w '^N'. 앤디가 그의 대본에서 똑같은 (기본) 아이디어로 나를 이길 때 나는 그것을 별도의 답변으로 작성하기를 꺼려했습니다. :)
syntaxerror

2

필자의 경우에는 이것을 사용하고 깨진 심볼릭 링크를 찾을 디렉토리를 알고 있으므로 꽤 잘 작동합니다.

find -L $path -maxdepth 1 -type l

내 폴더에는 링크가 포함되어 /usr/share있지만 통과하지는 않습니다. 크로스 장치 링크 및 chroot 등에 유효한 링크는 여전히 함정이지만 사용 사례로는 충분합니다.


2

OP 버전의 변형 인 간단한 노 브레이크 답변입니다. 때로는 입력하거나 기억하기 쉬운 것을 원할 수도 있습니다.

find . | xargs file | grep -i "broken symbolic link"

1

find -L . -type l |xargs symlinks 링크가 발견 된 파일별로 존재하는지 여부를 알려줍니다.


1

현재 디렉토리에서 깨진 심볼릭 링크의 이름이 인쇄됩니다.

for l in $(find . -type l); do cd $(dirname $l); if [ ! -e "$(readlink $(basename $l))" ]; then echo $l; fi; cd - > /dev/null; done

배쉬에서 작동합니다. 다른 껍질에 대해 모른다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.