add realpath_m.sh as an all-in-one replacement for realpath -m
parent
b9c659a70a
commit
dda942d7f1
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
realpath_canonical() {
|
||||
# resolve symlink (if there is one) and use $@ to detect symlink loops
|
||||
while [ -L "$1" ] && target=$(readlink -- "$1"); do
|
||||
REPLY=$(dirname "$1")
|
||||
# Resolve relative to symlink's directory
|
||||
if [ "$REPLY" = "." ]; then
|
||||
REPLY=$target
|
||||
else
|
||||
case "$target" in
|
||||
/*)
|
||||
REPLY=$target;;
|
||||
*)
|
||||
REPLY=$REPLY/$target;;
|
||||
esac
|
||||
fi
|
||||
# Break out if we found a symlink loop
|
||||
for target in "$@"; do [ "$REPLY" = "$target" ] && break 2; done
|
||||
# Add to the loop-detect list and tail-recurse
|
||||
set -- "$REPLY" "$@"
|
||||
done
|
||||
# recurse unless root
|
||||
REPLY=$(dirname "$1")
|
||||
if [ "$REPLY" != "/" ] && [ "$REPLY" != "." ]; then
|
||||
REPLY=$(realpath_canonical "$REPLY");
|
||||
fi
|
||||
# set $1 to dirname and $2 to basename
|
||||
set -- "$REPLY" "$(basename "$1")"
|
||||
# combine canon parent w/basename
|
||||
REPLY=$PWD
|
||||
while [ $# -gt 0 ]; do
|
||||
# handle case of component starting with double slash and no
|
||||
# other slashes separately because it cannot be solved by
|
||||
# globbing
|
||||
if echo "$1" | grep -E '^//[^/]*$' >/dev/null 2>&1; then
|
||||
REPLY=//
|
||||
first=$(echo "$1" | cut -c3-)
|
||||
shift
|
||||
set -- "$first" "$@"
|
||||
continue
|
||||
fi
|
||||
# all other cases can be expressed by globbing
|
||||
case $1 in
|
||||
/*)
|
||||
REPLY=/
|
||||
first=$(echo "$1" | sed -e 's/^\/\+//')
|
||||
shift
|
||||
set -- "$first" "$@"
|
||||
;;
|
||||
*/*)
|
||||
front=${1%%/*}
|
||||
back=$(echo "$1" | sed -e "s/^$front\\/\\+//")
|
||||
shift
|
||||
set -- "$front" "$back" "$@"
|
||||
;;
|
||||
''|.)
|
||||
shift
|
||||
;;
|
||||
..)
|
||||
REPLY=$(dirname "$REPLY")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
REPLY="${REPLY%/}/$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo "$REPLY"
|
||||
}
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "usage: $0 path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
realpath_canonical "$1"
|
Loading…
Reference in New Issue