상대 심볼릭 링크 대상의 절대 경로를 얻기 위해 테스트된 유틸리티를 찾고 있습니다.

상대 심볼릭 링크 대상의 절대 경로를 얻기 위해 테스트된 유틸리티를 찾고 있습니다.

알아채다:이 게시물의 원래 제목에서 나는 단어를 사용했습니다.기준일상적인 의미에서 "완벽"합니다(따라서 제가 직접 출시할 수 있는 빠른 수정 사항과 달리 오랜 시간 테스트를 거쳤습니다). 그러나 유닉스 대화의 맥락에서 용어는기준매우 구체적이고 매우 다른 기술적 의미를 갖습니다. 단어에 대한 또 다른 더 정확한 해석기준제목의 내용이 내 게시물의 나머지 부분과 일치하지 않게 만듭니다. (이 점을 지적해준 Stéphane Chazelas에게 감사드립니다.) 그래서 제목을 수정했습니다.기준그리고테스트를 거쳤습니다..


제목에서 언급한 질문의 예를 들어, 다음과 같은 디렉토리 구조가 있다고 가정해 보겠습니다.

/tmp/example
├── a/
│   └── b/
│       └── c/
│           └── d/
│               └── target
└── A/
    └── B/
        ├── C/
        │   └── D/
        │       └── symlink-0 -> ../../symlink-1/b/c/d/target
        └── symlink-1 -> /tmp/example/a

이는 /tmp/example/A/B/C/D/symlink-0심볼릭 링크입니다.즉각적인목표는 하나다비교적자취:

$ readlink /tmp/example/A/B/C/D/symlink-0
../../symlink-1/b/c/d/target

이에 해당하는 절대 경로를 얻고 싶습니다.즉각적인표적. IOW, 나는 처형하고 싶다부분의해결하다

/tmp/example/A/B/C/D/symlink-0 -> /tmp/example/A/B/symlink-1/b/c/d/target

이를 수행할 수 있는 표준(또는 적어도 성숙하고 오랜 테스트를 거친) Unix 유틸리티가 있습니까?


readlink -f구문 분석 경로에 주의하세요.완전히(비기호적 링크에 대한 경로), 예를 들면 다음과 같습니다.

$ readlink -f /tmp/example/A/B/C/D/symlink-0
/tmp/example/a/b/c/d/target

이는 readlink -f다음을 의미합니다.아니요제가 여기서 묻는 질문에 대한 답변입니다.


zsh다음 함수에 충분한 오류 검사 등을 추가하여 나만의 기능을 출시 할 수 있습니다 .

canonicalize () {
    local abspath=$(dirname $1)/$(readlink $1)
    printf -- '%s\n' $abspath:a
}

...그러나 나는 그러한 유틸리티를 강력하게 구현하는 것의 어려움을 과소평가하지 않는 법을 (어려운 방법으로) 배웠으므로 가능하다면 기존 도구를 사용하는 것을 선호합니다.


FWIW, 다음 스크립트는 이 게시물에 대한 예제를 생성합니다.

mkdir -p /tmp/example/a/b/c/d /tmp/example/A/B/C/D
touch /tmp/example/a/b/c/d/target
ln -s /tmp/example/a /tmp/example/A/B/symlink-1
ln -s ../../symlink-1/b/c/d/target /tmp/example/A/B/C/D/symlink-0

답변1

나는 그러한 유틸리티를 알지 못합니다. 그러나 귀하의 접근 방식에는 결함이 있습니다. 그리고 올바른 접근 방식이 어렵다는 데 동의합니다.

:a수정자는 파일 시스템에 액세스하지 않고 절대 경로를 계산합니다. 특히 심볼릭 링크인지 아닌지에 관계없이 로 변경됩니다 a/b/...aa/b

/a/b -> ../foo심볼릭 링크가 있는 경우 심볼릭 링크 자체가 아닌 경우에만 작동합니다 /foo. /a정규화하더라도 심볼릭 링크 자체인 것처럼 $(dirname $1)심볼릭 링크에 적용되지 않습니다 ./a/b -> x/../../foox

귀하의 경우:

/tmp/example/A/B/C/D/symlink-0 -> ../../symlink-1/b/c/d/target

심볼릭 링크 도 n이 아니기 /tmp/example/A/B/symlink-1/b/c/d/target때문에 해결됩니다 ./tmp/example/A/B/C/D/tmp/example/A/B/C

즉, ..구성 요소 없이 심볼릭 링크 대상에 대한 절대 경로를 얻으려면 여러 심볼릭 링크를 해결해야 할 수 있으며 이는 파일 경로와 심볼릭 링크 대상을 결합하여 단독으로 수행할 수 없습니다.

그러한 경로를 원한다면 가장 간단한(합리적이고 유용하다고 말하고 싶습니다) 방법은 다음과 같습니다.모델심볼릭 링크 대상에 대한 경로, 즉 모든 경로 구성 요소는 심볼릭 링크 ...심볼릭 링크도 아닙니다(마지막 항목 제외). 이렇게 하려면 다음을 수행할 수 있습니다.

zmodload -F zsh/stat b:zstat
canonicalize1() {
  if [ -L "$1" ]; then
    local link
    zstat -A link +link -- "$1" || return
    case $link in
      (/*) ;;
      (*)
        case $1:h in
          (*/) link=$1:h$link;;
          (*) link=$1:h/$link;;
        esac;;
    esac
    printf '%s\n' $link:h:A/$link:t
  else
    printf '%s\n' $1:A
  fi
}

귀하의 심볼릭 링크에서는 심볼릭 링크의 대상이 심볼릭 링크가 아니기 때문에 /tmp/example/A/B/C/D/symlink-0여전히 제공되지만 /tmp/example/a/b/c/d/target그것이 원하는 것이 아니라면 다음을 수행할 때 어떤 결과를 원하십니까?

canonicalize1 /tmp/x/y

/tmp/x/y에 대한 기호 링크는 어디에 있고 ../foo, 에 /tmp/x대한 기호 링크는 그 자체 가 기호 링크입니까?/a/b/c/a/a/b/a/b/c

관련 정보