Randal L. Schwartz <mer...@stonehenge.com> wrote:
Is a there a solution in perl which _isn't_ a one-liner!?
Here is a general purpose ksh script to do what you want.
=Brian
#! /bin/echo error: only source
#*TAG:42576 4:Jan 9 1973:0755:resolvepath:
# Author: Brian Hiles <b...@iname.com>
# Copyright: (c) 2000
# Description: resolve and canonicize full pathname of arguments
# Name: resolvepath
# Requires:
# Sccs: @(#)resolvepath.sh 1.8 1997/12 b...@iname.com (Brian Hiles)
# See-also: File-PathConvert-0.4.tar (perl)
# Usage: resolvepath [-hlp] path...
# Version: 1.08
#01
function resolvepath # [-hlp] path...
{ set -o noglob
# Ksh Bug: OPTIND cannot be declared integer!
typeset -i rc
typeset IFS OPTARG arg dir fn headers= symlink= oarg opt usepath=
while getopts :HhLlPp opt
do case $opt in
(h) headers=ON ;;
(+h|H) headers=OFF ;;
(l) symlink=ON ;;
(+l|L) symlink= ;;
(p) usepath=ON ;;
(+p|P) usepath= ;;
([:?]) print -ru2 "usage: $0 [-hlp] path...
-h - prepend the output with argument header
-l - show logical path with symlinks resolved [physical path]
-p - apply path lookup, if applicable"
return 2 ;;
esac
done
shift OPTIND-1
if [[ $headers = OFF ]]
then headers=
else (($#>1)) && headers=ON
fi
for arg
do oarg=$arg
if [[ $usepath = ON && ! -d $arg ]]
then # Ksh Bug: "whence" cannot handle args with spaces
arg=$(whence -p "$arg") ||
{ print -ru2 'resolvepath: whence: error:' \
"\"$oarg\" not found"
rc=rc+1 continue
}
fi
[[ -a $arg ]] ||
{ print -ru2 "resolvepath: error: \"$arg\" not found"
rc=rc+1 continue
}
[[ $arg != */* ]] && arg="./$arg"
if [[ -d $arg ]]
then dir=$arg fn=
else dir=${arg%/*} fn=${arg##*/}
fi
${DIAG:+print -ru2 "[ $0: dirpart=\"$dir\", filepart=\"$fn\" ]"}
# Ksh Bug: "cd -P dir" works, but "cd -P -- dir" does not!
[[ $dir = -* ]] && dir="./$dir" # work-around for above bug
\cd ${symlink:+-P} "$dir" || rc=rc+1 continue
print -r -- "${headers:+$oarg: }${PWD%/}/$fn" # <= TAB
\cd - >&-
done
return $rc
#02 EMBEDDED MAN-PAGE FOR "src2man"
: '
#++
NAME
resolvepath - resolve and canonicize the full pathname of argument
SYNOPSIS
resolvepath [-hlp] path...
OPTIONS
-h - Prepend the output with argument header.
-l - Show logical path with symlinks resolved. [physical path]
-p - Apply path lookup, if applicable.
DESCRIPTION
...
If and only if the path is a directory, the output is guaranteed
to be terminated with a slash ("/").
RETURN CODE
Returns 0 if successful, 2 for options parsing errors, otherwise
the number of arguments in error.
EXAMPLE
$ resolvepath .
/home/brian/side/lib/
$ resolvepath cat
resolvepath: error: "cat" not found
$ resolvepath -p cat
/bin/cat
$ resolvepath -lp cat
/usr/bin/cat
$ resolvepath /
/
$ resolvepath //
/
$ resolvepath /..
/
$ resolvepath /.//..///.////../////.//////..///////.////////..
/
ENVIRONMENT
PATH
SEE ALSO
predictshell(3S), stat(3S)
AUTHOR
Brian Hiles <b...@iname.com>
CAVEATS
The algorithm that is used requires the directory component of
the resolved argument to be executable; i.e. you must have
permission to chdir to it.
BUGS
Filenames with embedded spaces will be failed to be recognized;
this is a bug in the ksh builtin "whence", not resolvepath(3S).
#--
'