Last active
February 27, 2024 22:50
-
-
Save hilbix/1ec361d00a8178ae8ea0 to your computer and use it in GitHub Desktop.
Calculate relative path in BASH
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
: relpath A B | |
# Calculate relative path from A to B, returns true on success | |
# Example: ln -s "$(relpath "$A" "$B")" "$B" | |
relpath() | |
{ | |
local X Y A | |
# We can create dangling softlinks | |
X="$(readlink -m -- "$1")" || return | |
Y="$(readlink -m -- "$2")" || return | |
X="${X%/}/" | |
A="" | |
# See http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory | |
while Y="${Y%/*}" | |
[ ".${X#"$Y"/}" = ".$X" ] | |
do | |
A="../$A" | |
done | |
X="$A${X#"$Y"/}" | |
X="${X%/}" | |
echo "${X:-.}" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example use of relpath.inc, instead of "ln -vs A B" do "lns A B" | |
# idempotent, so no writes if everything is already OK | |
. "$(dirname "$0")/_relpath.inc" | |
OOPS() | |
{ | |
echo "OOPS: $*" >&2 | |
exit 1 | |
} | |
NOTE() | |
{ | |
echo "NOTE: $*" >&2 | |
} | |
lns() | |
{ | |
local R | |
if [ -L "$2" ] | |
then | |
# Check if both links are the same file | |
[ ".$(readlink -m -- "$1")" = ".$(readlink -m -- "$2")" ] && return | |
NOTE "replacing $2" | |
rm -vf "$2" | |
else | |
[ ! -e "$2" ] || OOPS "$2 exists and is no soflink" | |
NOTE "creating $2" | |
fi | |
# Note: $2 must not exist, else relpath fails! | |
R="$(relpath "$1" "$2")" || OOPS "relpath '$1' '$2'" | |
ln -vs "$R" "$2" | |
} | |
lns "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Renamed
relpath.inc
to_relpath.inc
to have GitHub list the correct filename in GIST.Note that
lns
is the shell function name, the shell script name is./linkit.sh A B