You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
44 lines
1.1 KiB
Bash
44 lines
1.1 KiB
Bash
relative_path() (
|
|
# both $1 and $2 are absolute paths beginning with /
|
|
# $1 must be a canonical path; that is none of its directory
|
|
# components may be ".", ".." or a symbolic link
|
|
#
|
|
# returns relative path to $2/$target from $1/$src
|
|
src=$1
|
|
target=$2
|
|
|
|
common_part=$src
|
|
result=
|
|
|
|
while [ "${target#"$common_part"}" = "$target" ]; do
|
|
# no match, means that candidate common part is not correct
|
|
# go up one level (reduce common part)
|
|
common_part=$(dirname "$common_part")
|
|
# and record that we went back, with correct / handling
|
|
if [ -z "$result" ]; then
|
|
result=..
|
|
else
|
|
result=../$result
|
|
fi
|
|
done
|
|
|
|
if [ "$common_part" = / ]; then
|
|
# special case for root (no common path)
|
|
result=$result/
|
|
fi
|
|
|
|
# since we now have identified the common part,
|
|
# compute the non-common part
|
|
forward_part=${target#"$common_part"}
|
|
|
|
# and now stick all parts together
|
|
if [ -n "$result" ] && [ -n "$forward_part" ]; then
|
|
result=$result$forward_part
|
|
elif [ -n "$forward_part" ]; then
|
|
# extra slash removal
|
|
result=${forward_part#?}
|
|
fi
|
|
|
|
printf '%s' "$result"
|
|
)
|