On Tue, Aug 9, 2011 at 2:14 PM, Bob Proulx <b...@proulx.com> wrote: > Jon Seymour wrote: >> I always use sed for this purpose, so: >> >> $(cd "$dir"; ls -l "$base" | sed "s/.*->//") >> >> But, with pathological linking structures, this isn't quite enough - >> particularly if the target of the link itself contains paths, some of >> which may contain links :-) > > Agreed! Symlinks with arbitrary data, such as holding small shopping > lists in the target value, are so much fun. I am more concerned that > arbitrary data such as "->" might exist in there more so than > whitespace. That is why I usually don't use a pattern expression. > But I agree it is another way to go. But it is easier to say > whitespace is bad in filenames than to say whitespace is bad and oh > yes you can't have "->" in there either. :-) >
Ok, I think this does it... readlink_f() { local path="$1" test -z "$path" && echo "usage: readlink_f path" 1>&2 && exit 1; local dir if test -L "$path" then local link=$(ls -l "$path" | sed "s/.*-> //") if test "$link" = "${link#/}" then # relative link dir="$(dirname "$path")" readlink_f "${dir%/}/$link" else # absolute link readlink_f "$link" fi elif test -d "$path" then (cd "$path"; pwd -P) # normalize it else dir="$(cd $(dirname "$path"); pwd -P)" base="$(basename "$path")" echo "${dir%/}/${base}" fi }