Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

equivalent of stdlib.h's realpath() in a shell script?

111 views
Skip to first unread message

Benjamin Rutt

unread,
Apr 29, 2002, 8:36:57 PM4/29/02
to
There are times when I need to convert a file path into an absolute
path. For this, I've written a C program which I named 'realpath'
which invokes stdlib.h's realpath() method. I call this program from
a shell script.

Is there another way to convert file paths into absolute/canonical
paths using some shell functions or one of the more commonly available
tools? It would be nice to avoid having to take my C program around
and build it on all the systems I use.
--
Benjamin

David Thompson

unread,
Apr 29, 2002, 10:00:26 PM4/29/02
to
"Benjamin Rutt" <rutt...@cis.ohio-state.edu> wrote

Try using something like,

set_actual_dir()
{
ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`
}

In some cases, I've found I've had to use the /bin/pwd
rather than the builtin.

--
David Thompson
dat...@yahoo.com


Benjamin Rutt

unread,
Apr 29, 2002, 11:34:03 PM4/29/02
to
"David Thompson" <dat...@yahoo.com> writes:

[...]

> Try using something like,
>
> set_actual_dir()
> {
> ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`
> }

I guess that would work for directories, but not for regular files or
symlinks. I guess I really wanted it for those.
--
Benjamin

Benjamin Rutt

unread,
Apr 29, 2002, 11:34:41 PM4/29/02
to
"David Thompson" <dat...@yahoo.com> writes:

[...]

> Try using something like,


>
> set_actual_dir()
> {
> ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`
> }

I guess that would work for directories, but not for regular files or
symlinks. I guess I really wanted it for all of the above.
--
Benjamin

David Thompson

unread,
Apr 30, 2002, 12:06:39 AM4/30/02
to
"Benjamin Rutt" <rutt...@cis.ohio-state.edu> wrote

Are you using ksh93? If so, use the -P option of pwd.

Change this line,

ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`

to this,

ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd -P)`

Read about -P option in builtin commands section at,

http://www.cs.princeton.edu/~jlk/kornshell/doc/man93.html

--
David Thompson
dat...@yahoo.com


Chris F.A. Johnson

unread,
Apr 30, 2002, 12:17:39 AM4/30/02
to
In article <iLoz8.165820$G72.91899@sccrnsc01>, David Thompson wrote:
> "Benjamin Rutt" <rutt...@cis.ohio-state.edu> wrote
>> "David Thompson" <dat...@yahoo.com> writes:
>>
>> [...]
>>
>> > Try using something like,
>> >
>> > set_actual_dir()
>> > {
>> > ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`
>> > }
>>
>> I guess that would work for directories, but not for regular files or
>> symlinks. I guess I really wanted it for those.
>
> Are you using ksh93? If so, use the -P option of pwd.

Ditto for bash.

Also, the GNU version of the pwd command resolves symlinks.

> Change this line,
>
> ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd)`
>
> to this,
>
> ACTUAL_DIR=`(cd "$1" 2> /dev/null && pwd -P)`
>
> Read about -P option in builtin commands section at,
>
> http://www.cs.princeton.edu/~jlk/kornshell/doc/man93.html

--
Chris F.A. Johnson bq...@torfree.net
=================================================================
c.f.a....@rogers.com http://cfaj.freeshell.org
cf...@freeshell.org http://members.rogers.com/c.f.a.johnson

Brian Hiles

unread,
Apr 30, 2002, 8:54:57 PM4/30/02
to
Benjamin Rutt <rutt...@cis.ohio-state.edu> wrote:
> I guess that would work for directories, but not for regular files or
> symlinks. I guess I really wanted it for all of the above.

Try my function, "resolvepath," which allows optional resolution of path
and symlinks. Read the manual page that appends the function.

=Brian

#! /bin/echo error: only source
#*TAG:28153 4:Jun 16 1973:0755:../lib/resolvepath:
# Author: Brian Hiles <b...@iname.com>
# Copyright: (c) 2000
# Description: resolve and canonicize full pathname of arguments
# Name: resolvepath
# Project: @(#)resolvepath.sh 1.8 1997/12 b...@iname.com (Brian Hiles)
# Requires:
# See-also: File-PathConvert-0.4.tar (perl)
# See-also: pathconvert: http://wafu.netgate.net/tama/unix/indexe.html (C)
# Usage: resolvepath [-hlp] path...
# Version: 1.08

#01
function resolvepath # [-hlp] path...
{ set -o noglob
# Ksh Bug: OPTIND cannot be declared integer!
OPTIND=1 typeset -i rc=0
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
...

The directory components are guaranteed to be separated by one
and only one slash ("/") character.

If and only if the path is a directory, the output is guaranteed
to be terminated with one slash ("/") character.

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).

#--
'

Brian Hiles

unread,
May 6, 2002, 7:20:42 PM5/6/02
to
Brian Hiles <b...@rawbw.com> wrote:
> Benjamin Rutt <rutt...@cis.ohio-state.edu> wrote:

Darn! Who is the genius who thought to allow the default behavior of a
news browser to do semantic substitutions of <asterisk>text<asterisk> and
<underscore>text<underscore> ?!

I can do no better than to experiment by reposting my function source,
which was eviscerated by the aforementioned nonsense.

Here goes nothing:

0 new messages