On Sun, Nov 13, 2011 at 12:45 PM, Dmitry V. Levin <l...@altlinux.org> wrote: > Hi, > > On Sat, Nov 12, 2011 at 11:45:56AM -0700, Eric Blake wrote: > [...] >> http://docs.python.org/library/os.path.html >> >> os.path.relpath(path[, start]) >> >> >> >> Return a relative filepath to path either from the current directory >> >> or from an optional start point. >> >> Ah, so the idea is that python has a function that computes a relative >> pathname to one path given a starting point: >> >> $ relpath /usr/bin /tmp >> ../usr/bin >> $ relpath /usr/bin /usr/share >> ../bin > > Btw, there is an utility in freebsd ports called relpath:
This is good to know. Just to double check. Due to the license for the FreeBSD's relpath, it can not be copied to coreutils. Right? > http://www.freebsd.org/cgi/cvsweb.cgi/ports/sysutils/relpath/ > ftp://ftp.freebsd.org/pub/FreeBSD/ports/local-distfiles/beech/relpath-0.1.0.tar.gz > > $ lftp -c 'cat > http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/sysutils/relpath/pkg-descr' > Usage: relpath [-d DIR] START_DIR END_PATH > > Find a relative path from START_DIR to END_PATH. > Prints the relative path on standard out. > > If -d DIR, then only emit a relative path if both > START_DIR and END_PATH are sub-directories of DIR; > otherwise, emit an absolute path to END_PATH. > >> This seems like you could do it in shell without resorting to python, by >> computing a canonical name for both the destination and the starting >> point, then comparing common prefixes, and for every directory component >> that differs after the common prefix, replacing the directory with >> '../'. This has been done before; for example, this is from gnulib-tool: >> >> # func_relativize DIR1 DIR2 >> # computes a relative pathname RELDIR such that DIR1/RELDIR = DIR2. >> # Input: >> # - DIR1 relative pathname, relative to the current directory >> # - DIR2 relative pathname, relative to the current directory >> # Output: >> # - reldir relative pathname of DIR2, relative to DIR1 >> func_relativize () >> { >> dir0=`pwd` >> dir1="$1" >> dir2="$2" >> sed_first='s,^\([^/]*\)/.*$,\1,' >> sed_rest='s,^[^/]*/*,,' >> sed_last='s,^.*/\([^/]*\)$,\1,' >> sed_butlast='s,/*[^/]*$,,' >> while test -n "$dir1"; do >> first=`echo "$dir1" | sed -e "$sed_first"` >> if test "$first" != "."; then >> if test "$first" = ".."; then >> dir2=`echo "$dir0" | sed -e "$sed_last"`/"$dir2" >> dir0=`echo "$dir0" | sed -e "$sed_butlast"` >> else >> first2=`echo "$dir2" | sed -e "$sed_first"` >> if test "$first2" = "$first"; then >> dir2=`echo "$dir2" | sed -e "$sed_rest"` >> else >> dir2="../$dir2" >> fi >> dir0="$dir0"/"$first" >> fi >> fi >> dir1=`echo "$dir1" | sed -e "$sed_rest"` >> done >> reldir="$dir2" >> } >> >> Doing it in fewer processes seems possible with something like a single >> awk script, although I haven't tried writing one; at any rate, awk would >> be more portable than python for the same task. >> >> But yes, providing this as an alternative mode of coreutils' realpath >> instead of scripting it in shell or awk seems like a useful addition - >> would you care to submit a patch? > > AFAIR the coreutils' realpath is called readlink. ;) > > Would "readlink --relative" or something like this be a good choice? > Or should it rather be a new utility? I think a new utility relpath will be more descriptive. -- Regards, Peng