[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ln and relative paths
From: |
Nicolai Langfeldt |
Subject: |
ln and relative paths |
Date: |
Wed, 28 Nov 2001 14:10:27 +0100 |
Hi,
Firstly, thanks for all the great work on the gnu utils.
Secondly, two feature requests.
- ln does not have a option to generate relative symlinks paths from
absolute paths. This seems a odd omission in a execlent program :-)
So I wrote a bash function to satisfy my immediate needs, I have
appended it for inspiration :-) I belive gnu tar has some paths to do
such conversions.
- It would also be nice with a 'do what I said' option. Given
ln -s /foo/bar /gazonk/bar-link
to symlink the directory /gazonk/bar-link -> /foo/bar this works as I
said the first time, the second time it creates /gazonk/bar-link/bar
alias /foo/bar/bar because it decuces that I want to create a link to
bar inside bar-link since bar-link exists and is a directory. Getting
around this in a shell script in a robust way takes a bit too much
effort it seems.
rln () {
# Oddly GNU ln does not have an option to link with relative path.
# So here we Calculate the relative path. Paths with space in will
# not work, but paths with . and .. in are handled
ARG="$1"; shift || exit 1
LINK="$1"; shift || exit 1
NEW="$1"; shift || exit 1
# echo Transform ln $ARG $LINK $NEW
# Check if $FROM is absolute, and has no spaces
case $LINK in
*\ *) exit 1;; # NO SPACES!
/*) :;;
*) ln $ARG "$LINK" "$NEW"
;;
esac
# Check that the new name has no spaces
case $NEW in
*\ *) exit 1;;
esac
test -e "$LINK" || return
# Find common leading path elements, replace / in paths with ' '
# and put in array for processing. Remove /../ and /./ in the
# process.
ALINK=($(echo "$LINK" |
sed -e 's~/[^/]*/\.\./~/~g' -e 's~/./~/~g' |
tr '/' ' '))
ANEW=($(echo "$NEW" |
sed -e 's~/[^/]*/\.\./~/~g' -e 's~/./~/~g' |
tr '/' ' '))
I=0
while [ "${ALINK[$I]}" = "${ANEW[$I]}" ] ; do
unset ALINK[$I]
unset ANEW[$I]
I=$(($I + 1))
done
# Now the task left is to count how many directory levels we have to
go up
ALINK="$(echo address@hidden | tr ' ' /)"
ANEW="$(echo address@hidden | tr ' ' /)"
# echo "Non common paths are $ALINK $ANEW"
ANEW="$(dirname $ANEW)"
while [ "$ANEW" != . ] ; do
ALINK="../$ALINK"
ANEW="$(dirname $ANEW)"
done
# echo ln $ARG "$ALINK" "$NEW"
ln $ARG "$ALINK" "$NEW"
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- ln and relative paths,
Nicolai Langfeldt <=