심볼릭 링크 체인을 나열하는 방법?


답변:


65

그냥 사용하십시오 namei:

$ namei d
f: d
 l d -> c
   l c -> b
     l b -> a
       d a

5
틸. 이것은 멋진 명령입니다. 공감
톰 오코너

op에서 요청한대로 전체 링크 체인을 표시하므로 허용되는 답변이어야합니다. 또한와 유사한 전체 디렉토리를 나열하는 데 사용할 수 있습니다 ls. 감사!
공포증

실제로이 게시물을 다시 방문하고 있으며 namei는 훌륭한 명령입니다!
Kalecser

프로그램의 실제 사용법을 찾으려면 "which"명령과 함께 사용하십시오 : $ namei`which java`
pdem

18

readlink -e <link>

readlink [OPTION] ... 파일


  • 주어진 이름의 모든 구성 요소에있는 모든 심볼릭 링크를 재귀 적으로 따라 가면 기존 구성 요소가 정규화됩니다.
$ mkdir testlink
$ cd testlink
pjb@pjb-desktop:~/testlink$ ln -s c b
pjb@pjb-desktop:~/testlink$ ln -s b a
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
pjb@pjb-desktop:~/testlink$ echo foo > c
pjb@pjb-desktop:~/testlink$ cat a
foo
pjb@pjb-desktop:~/testlink$ readlink -e a
/home/pjb/testlink/c

참고 : readlink a 자체는 b를 반환합니다.

참고 # 2 : 체인을 나열하는 유틸리티 인 find -l과 함께 펄로 쉽게 작성할 수 있지만 루프를 감지 할만큼 똑똑해야합니다.

루프가 있으면 readlink가 아무것도 출력하지 않습니다. 이것은 붙어있는 것보다 낫습니다.

pjb@pjb-desktop:~/testlink$ ln -sf a c
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:03 c -> a
pjb@pjb-desktop:~/testlink$ readlink -e a
pjb@pjb-desktop:~/testlink$ # (note: no output)

OS X : brew install coreutilsgreadlink -e <link>
Jose Alban

3

Bash의 재귀 함수는 다음과 같습니다.

chain() { export chain; local link target; if [[ -z $chain ]]; then chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; chain+=" -> $target"; chain "$target"; return; done; echo "$chain"; unset chain; }

여러 줄에서 :

chain() {
    export chain
    local link target
    if [[ -z $chain ]]
    then
        chain="$1"
    fi
    link=$(stat --printf=%N "$1")
    while [[ $link =~ \-\> ]]
    do
        target="${link##*\`}"
        target="${target%\'}"
        chain+=" -> $target"
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target"
        return
    done
    echo "$chain"
    unset chain
}

예 :

$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a

그것은 필요 stat(1)일부 시스템에서는 존재하지 않을 수있다.

이름에 백틱, 작은 따옴표 또는 "->"가 포함되어 있으면 실패합니다. symlink 루프가있는 루프에 갇히게됩니다 (Bash 4의 연관 배열을 사용하여 해결할 수 있음). 이미 사용 중인지 여부에 관계없이 "chain"이라는 변수를 내 보냅니다.

다른 문제가있을 수 있습니다.

편집하다:

일부 상대 심볼릭 링크 관련 문제를 수정했습니다. 일부는 여전히 작동하지 않지만 아래 버전에서는 링크 대상이 필요하지 않습니다.

readlink를 사용하는 버전을 추가했습니다 :

chain ()
{
    export chain;
    local target;
    if [[ -z $chain ]]; then
        chain="$1";
    fi;
    target=$(readlink "$1");
    while [[ $target ]]; do
        chain+=" -> $target";
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target";
        return;
    done;
    echo "$chain";
    unset chain
}

스크립트를 테스트했지만 실제로 작동하지만 더 간단한 것을 선호하므로 불완전한 경우에도 다른 답변을 수락했습니다.
Kalecser

1
좋은 대본. 때때로 나는 전체 체인을보고 싶어하지만 그것을 readlink보이지 않는 것 같습니다. Ubuntu의 Java는 다음과 같습니다./usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski

0

namei의 출력을 후 처리 awk하거나 grep원하는 줄로 얻을 수 있습니다.

namei d | awk '$1=="l"'

또는

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