realpath.sh/realpath.sh

66 lines
1011 B
Bash
Raw Normal View History

2018-03-14 00:26:12 +01:00
#!/bin/sh
2018-03-16 05:07:09 +01:00
case "$1" in
2018-03-16 05:11:59 +01:00
/*)
left="${1#/}"
;;
*)
left="${PWD#/}/$1"
;;
2018-03-16 05:07:09 +01:00
esac
2018-03-14 00:26:12 +01:00
2018-03-16 05:10:20 +01:00
result=""
2018-03-14 00:26:12 +01:00
2018-03-16 05:10:20 +01:00
while [ -n "$left" ]; do
case "$left" in
*/*)
# Snip one path segment off $left
2018-03-16 05:10:20 +01:00
seg="${left%%/*}"
left="${left#*/}"
;;
*)
# Last path segment already
2018-03-16 05:10:20 +01:00
seg="$left"
left=""
;;
esac
case "$seg" in
.)
2018-03-20 19:03:13 +01:00
# Just ignore this segment
continue
;;
..)
2018-03-20 19:03:13 +01:00
# Eat a segment off result
result="${result%/*}"
continue
;;
esac
2018-03-16 05:10:20 +01:00
result="$result/$seg"
target="$(readlink "$result")"
case "$target" in
2018-03-16 05:11:59 +01:00
/*)
# Absolute symlink. Resets buildup of $result
left="${target}/${left}"
2018-03-16 05:11:59 +01:00
result=""
;;
'')
# Readlink failed, its not a symlink
2018-03-20 18:40:47 +01:00
# If file does not exist, exit
[ -e "$result" ] || exit 1
2018-03-16 05:11:59 +01:00
;;
*)
# Relative symlink: Keep $result, its the symlink base
left="${target}/${left}"
result="${result%/*}"
2018-03-16 05:11:59 +01:00
;;
esac
# Make sure $left never starts with a slash
2018-03-16 05:10:20 +01:00
left="${left#/}"
done
2018-03-16 05:24:15 +01:00
printf "%s\n" "$result"