scripts/functions: CanonPath: new function (canonicalize each path component except for the last)

This is actually a DWIM-style hack.  It does what we want but I cannot
think of a better name.  The idea is that sometimes we want to clean
up path name, possibly following symbolic links, except for the last
component, which we want to keep as is.

$ sh -c '. scripts/functions; CanonPath /etc/init.d/functions'
/etc/rc.d/init.d/functions
$ sh -c '. scripts/functions; CanonPath /usr/bin/../bin/perl'
/usr/bin/perl
$

So actually it does a few different things: 1) prepend $PWD if needed;
2) cleanup dirname; 3) canonicalize dirname with respect to symbolic links.

Now the question is how to process symbolic links which
targets are directories, e.g. /etc/init.d ?  My answer is that
both "/etc/init.d" and "/etc/init.d/", as well as "/etc/init.d/."
should yield the same result, which is "/etc/rc.d/init.d".
This commit is contained in:
Alexey Tourbin 2007-08-27 20:41:02 +04:00
parent 32909e6a8a
commit 5a5bd82133

View File

@ -99,6 +99,23 @@ RunMethods()
done
}
CanonPath()
{
local f="$1" f2; shift
if [ -d "$f" ]; then
f2=$(readlink -vm -- "$f")
elif [ -L "$f" ]; then
local d
d=$(dirname -- "$f")
d=$(readlink -vm -- "$d")
f2="$d/${f##*/}"
else
f2=$(readlink -vm -- "$f")
fi
[ "$f" = "$f2" ] || Verbose "CanonPath: $f -> $f2"
echo "$f2"
}
ArgvFileAction()
{
local av_action="$1"; shift
@ -126,14 +143,14 @@ ArgvFileAction()
local av_f
if [ $# -gt 0 ]; then
for av_f; do
[ -n "$av_f" -a -z "${av_f##/*}" ] || av_f=$(readlink -vm -- "$av_f")
[ -n "$av_f" -a -z "${av_f##/*}" ] || av_f=$(CanonPath "$av_f")
Debug "processing $av_f"
"$av_action" "$av_f"
done
else
[ -t 0 ] && Info "reading file list from standard input"
while IFS= read -r av_f; do
[ -n "$av_f" -a -z "${av_f##/*}" ] || av_f=$(readlink -vm -- "$av_f")
[ -n "$av_f" -a -z "${av_f##/*}" ] || av_f=$(CanonPath "$av_f")
Debug "processing $av_f"
"$av_action" "$av_f"
done