두 디렉토리 사이의 상대 경로를 얻는 방법은 무엇입니까?

두 디렉토리 사이의 상대 경로를 얻는 방법은 무엇입니까?

경로가 있는 변수가 있고 release/linux/x86다른 디렉토리(예: 현재 작업 디렉토리)의 상대 경로를 원한다고 가정합니다 ../../... 쉘 명령(또는 GNU Make)에서 어떻게 얻을 수 있습니까?

소프트 링크 지원이 필요하지 않습니다.


이 질문은 용어를 개선하기 위해 허용된 답변에서 크게 수정되었습니다.

답변1

그 목적이 무엇인지는 확실하지 않지만 요청한 대로 정확하게 수행됩니다.GNU 실제 경로:

realpath -m --relative-to=release/linux/x86 .
../../..
realpath -m --relative-to=release///./linux/./x86// .
../../..

답변2

이는 디스크나 네트워크 액세스 없이 문자열 조작(셸 인수 확장을 통해)만 사용하여 원본에서 대상 디렉터리까지의 상대 경로를 반환하는 셸 함수입니다. 경로 이름 없음 해결하다 이미 마쳤어.

두 개의 매개변수(source-dir 및 target-dir)가 필요하며 둘 다 완전히 정규화된 비어 있지 않은 경로 이름입니다. 둘 다 /-로 끝날 수 있으며 둘 다 존재할 필요가 없습니다. 비어 있으면 결과는 후행 없이 $REPLY소스 디렉터리에서 대상 디렉터리까지의 상대 경로로 셸 변수에 반환됩니다 ./.

2005년 comp.unix.shell 게시물의 알고리즘이 이제 다음으로 업데이트되었습니다.Archive.org.

pnrelpath() {
    set -- "${1%/}/" "${2%/}/" ''               ## '/'-end to avoid mismatch
    while [ "$1" ] && [ "$2" = "${2#"$1"}" ]    ## reduce $1 to shared path
    do  set -- "${1%/?*/}/"  "$2" "../$3"       ## source/.. target ../relpath
    done
    REPLY="${3}${2#"$1"}"                       ## build result
    # unless root chomp trailing '/', replace '' with '.'
    [ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}

사용

$ pnrelpath "$HOME" "$PWD"
projects/incubator/nspreon
$ pnrelpath "$PWD" "$gimpkdir"
../../../.config/GIMP
$ pnrelpath "$PWD" "$(cd "$dirnm" && pwd || false)"
# using cd to resolve, canonicalize ${dirnm}

아니면통일 자원 식별자나누는 scheme://authority,

$ pnrelpath 'https://example.com/questions/123456/how-to' 'https://example.com/media'
../../../media

고쳐 쓰다2022년 11월 24일

while이전 함수의 문을 건너뛰면 다음이 반환됩니다 realpath --relative-base. 대상이 소스 내부 또는 아래에 있으면 소스에서 대상 디렉터리까지의 상대 경로가 반환되고, 그렇지 않으면 절대 경로가 반환됩니다. 유사한 사전 및 사후 조건이 적용됩니다.

pnrelbase() {
    set -- "${1%/}/" "${2%/}/"      ## '/'-end to avoid mismatch
    REPLY="${2#"$1"}"               ## build result
    # unless root chomp trailing '/', replace '' with '.'
    [ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}

(업데이트 종료)

관련 정보