Angenommen, ich habe eine Variable mit einem Pfad release/linux/x86
und möchte den relativen Pfad von einem anderen Verzeichnis (also ../../..
dem aktuellen Arbeitsverzeichnis). Wie erhalte ich diesen in einem Shell-Befehl (oder möglicherweise mit GNU Make)?
Softlink-Unterstützung nicht erforderlich.
Diese Frage wurde auf der Grundlage der akzeptierten Antwort zur Verbesserung der Terminologie stark modifiziert.
Antwort1
Der Zweck ist absolut nicht klar, aber es wird genau das tun, was gefragt wurde, mitGNU Realpath:
realpath -m --relative-to=release/linux/x86 .
../../..
realpath -m --relative-to=release///./linux/./x86// .
../../..
Antwort2
Hier ist eine Shell-Funktion, die einen relativen Pfad vom Quell- zum Zielverzeichnis zurückgibt, indem sie nur String-Manipulationen verwendet - durch Shell-Parametererweiterung - ohne Festplatten- oder Netzzugriff. Kein Pfadname Auflösung erledigt.
Erwartet zwei Parameter, Quellverzeichnis und Zielverzeichnis, beides absolute kanonisierte, nicht leere Pfadnamen, die beide /
mit - enden können und nicht unbedingt vorhanden sein müssen. Gibt das Ergebnis in der Shell-Variable $REPLY
als relativen Pfad vom Quellverzeichnis zum Zielverzeichnis ohne abschließendes - zurück /
, .
wenn es nichtig ist.
Der Algorithmus stammt aus einem comp.unix.shell-Posting von 2005, das inzwischen aufgestiegen ist zuarchive.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:-.}"
}
Benutzen als
$ pnrelpath "$HOME" "$PWD"
projects/incubator/nspreon
$ pnrelpath "$PWD" "$gimpkdir"
../../../.config/GIMP
$ pnrelpath "$PWD" "$(cd "$dirnm" && pwd || false)"
# using cd to resolve, canonicalize ${dirnm}
oder mitURIs teilen scheme://authority
,
$ pnrelpath 'https://example.com/questions/123456/how-to' 'https://example.com/media'
../../../media
Aktualisieren24.11.2022
Wenn Sie die while
Anweisung in der vorherigen Funktion überspringen, wird Folgendes zurückgegeben realpath --relative-base
: ein relativer Pfad vom Quell- zum Zielverzeichnis, wenn das Ziel in oder unter der Quelle liegt, andernfalls ein absoluter Pfad. Es gelten ähnliche Bedingungen vor und nach der Anweisung.
pnrelbase() {
set -- "${1%/}/" "${2%/}/" ## '/'-end to avoid mismatch
REPLY="${2#"$1"}" ## build result
# unless root chomp trailing '/', replace '' with '.'
[ "${REPLY#/}" ] && REPLY="${REPLY%/}" || REPLY="${REPLY:-.}"
}
(Update Ende)