bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: equivalent of Linux readlink -f in pure bash?


From: Jon Seymour
Subject: Re: equivalent of Linux readlink -f in pure bash?
Date: Tue, 9 Aug 2011 14:36:52 +1000

On Tue, Aug 9, 2011 at 2:14 PM, Bob Proulx <bob@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
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]