-
Notifications
You must be signed in to change notification settings - Fork 0
/
readlinkf_posix
executable file
·42 lines (35 loc) · 1.07 KB
/
readlinkf_posix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env sh
set -eu
# POSIX compliant version of readlink
# Credit: https://github.com/ko1nksm/readlinkf
if [ ${#} -eq 0 ]; then
printf "%s\n" "readlinkf: no file path provided"
exit 0
fi
[ "${1:-}" ] || return 1
max_symlinks=40
# to avoid changing to an unexpected directory
CDPATH=''
target=${1}
# trim trailing slashes
[ -e "${target%/}" ] || target=${1%"${1##*[!/]}"}
[ -d "${target:-/}" ] && target="$target/"
cd -P . 2>/dev/null || return 1
while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do
if [ ! "$target" = "${target%/*}" ]; then
case $target in
/*) cd -P "${target%/*}/" 2>/dev/null || break ;;
*) cd -P "./${target%/*}" 2>/dev/null || break ;;
esac
target=${target##*/}
fi
if [ ! -L "$target" ]; then
target="${PWD%/}${target:+/}${target}"
printf '%s\n' "${target:-/}"
exit 0
fi
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html
link=$(ls -dl -- "$target" 2>/dev/null) || break
target=${link#*" $target -> "}
done
exit 1