[comp.sys.sgi] Symbolic Links for Lunks

root@MCIRPS2.MED.NYU.EDU (08/08/90)

After having clobbered too many  very important files and directories that
I wanted to make local symlinks to, I wrote the script below to
make it more difficult for me to clobber my files with sgi symbolic
links. Use it in good health. I would be interested in your improvements too!

#! /bin/sh
# Less dangerious and more user frendly front end for ln -s .
# Prevents you from making symbolic linkages the wrong way and clobbering what
# you want to link to.

clear
# . Version.mac #a macro that records who and how often this is used.
file="$1"

echo "Enter existing file you wish create a link to"
if [ "$1" ]
then
echo "or enter a return to use $1"
fi

read file

        if [ -z "$file" ]
        then
        file=$1
        fi

        if [ -x $file ]
        then
        echo "GOOD. $file exists"
        ls -ld $file
        else
        echo "$file does not exist"
        echo " How do you expect me to make a link to a file I can't find."
        echo " bad bad boy"
        exit 1
        fi

echo "\n\n"

echo "Enter name of link to create $2"

        if [ -z "$2" ]
        then
        echo "or return to use `basename $file`"
        fi

read link

        if [ -z "$link" ]
        then
        link=$2
        fi

        if [ -z "$link" ]
        then
        link=`basename $file`
        echo "do you want me to use $link as your local link to \n$file ?"
        echo "\nReturn to continue,anything else aborts."
        read ans
                if [ -n "$ans" ]
                then
                exit 1
                fi
        fi

        if [ -x $link ]
        then
        echo "bad bad bad boy, $link exists. If you don't believe me, look"
        ls -ld $link
        exit 1
        else
        echo "nice kitty"
        echo " $link is ready to create"
        fi

ln -s $file $link
echo "\n\n"
ls -ld $file $link | cut -c1-10,40-

echo "$0 :Completed"
# . End.mac
exit 0

+-----------------------------------------------------------------------------+
| karron@nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+

vjs@rhyolite.wpd.sgi.com (Vernon Schryver) (08/08/90)

In article <9008072310.AA21830@mcirps2.med.nyu.edu>, root@MCIRPS2.MED.NYU.EDU writes:
> 
> After having clobbered too many  very important files and directories that
> I wanted to make local symlinks to, I wrote the script below to
> make it more difficult for me to clobber my files with sgi symbolic
> links. ...


Could you suggest improvements to the -i option of ln, as in `ln -si foo bar`,
described in ln(1), to make ln as safe as your script?


Vernon Schryver
vjs@sgi.com

karron@MCIRPS2.MED.NYU.EDU (08/10/90)

The problem seems to be more than I first thought. If you want to make a
link, It seems that you have to use a fully qualified file path or the
symbolic link can get lost...

Try to cd to some directory, and then link a file there back to another file
link in a non local directory (some other directory other than the one you
are using as your cwd). I have to fix the script (again) to fully expand
a file name prior to making the links.

I did not know that the ln -is option worked. I just tried it, and it
gave me a cryptic warning "files identical". My problem is getting
the order correct, so that I don't overwrite my file with a symlink pointing
to itself. Anyway, sgi (youse guys) should fix it better. Perhaps if the
code it not a trade secret, post it so we can make our own versions. Or
just use a shell script front end, or just be more careful.

The reason I am using links more and more is to save disk space, and not keep
copies of hugh image files local, but on remote file systems with long path
names. Keeping a local symlink is really neat !

dan(who should read the man page prior to solving the problem)
+-----------------------------------------------------------------------------+
| karron@nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+

karron@MCIRPS2.MED.NYU.EDU (08/10/90)

There was a problem with creating links from outside your current working
directory that I think I fixed in this version of the script, and a bug in
file existance testing ( [ -x ] for [ -f ] ) that would not let you link to a
nonexecutable file.

I think that this works.  While not the most artful shell script, This is what
I use to protect myself from some of the problems with symbolic links.

It has been pointed out to me that ln -si will prevent you from clobbering
a file with a link too. Then my only improvement is that this script
checks for existance of files to link to and qualifies file paths
relative to root so that you can't get a dangling link (a linkage to a
file that does not exist because it is being evaluated relative to some
arbitrary current working location).

Thanks for all your input, and I hope that this works better.
---------cut here--------------------------------------------------------------
#! /bin/sh
# more user frendly front end for ln -s
# prevents you from making linkages the wrong way and clobbering what
# you want to LINK to.
#
# fully qualifies FILE and LINK names so you
#   don't get dangling linkages.

clear
#. Version.mac
FILE="$1"

        if echo $FILE | egrep -s "^/"
        then
        echo "File name is fully qualified"
        else
        echo "File name being qualified"
        FILE_DIR_NAME=`dirname $FILE`
        FILE="`(cd $FILE_DIR_NAME;pwd)`/`basename $FILE`"
        fi

echo "Enter existing file you wish create a link to"

        if [ "$1" ]
        then
        echo "or enter a return to use $FILE"
        fi

read FILE

        if [ -z "$FILE" ]
        then
        FILE=$1
        fi

        if echo $FILE | egrep -s "^/"
        then
        echo "File name is fully qualified"
        else
        echo "File name being qualified"
        FILE_DIR_NAME=`dirname $FILE`
        FILE="`(cd $FILE_DIR_NAME;pwd)`/`basename $FILE`"
        fi

        if [ -f $FILE ]
        then
        echo "GOOD. $FILE exists"
        ls -ld $FILE
        else
        echo "$FILE does not exist"
        echo " How do you expect me to make a link to a file I can't find."
        exit 1
        fi

echo "\n\n"
LINK="$2"

        if echo $LINK | egrep -s "^/"
        then
        echo "Link name is fully qualified"
        else
        echo "Link name being qualified"
        LINK_DIR_NAME=`dirname $LINK`
        LINK="`(cd $LINK_DIR_NAME;pwd)`/`basename $LINK`"
        fi

echo "Enter name of link to create $LINK"

        if [ -z "$2" ]
        then
        echo "or return to use `basename $FILE`"
        fi

read LINK

        if [ -z "$LINK" ]
        then
        LINK=$2
        fi

        if echo $LINK | egrep -s "^/"
        then
        echo "Link name is fully qualified"
        else
        echo "Link name being qualified"
        LINK_DIR_NAME=`dirname $LINK`
        LINK="`(cd $LINK_DIR_NAME;pwd)`/`basename $LINK`"
        fi

        if [ -z "$LINK" ]
        then
        LINK=`basename $FILE`
        echo "do you want me to use $LINK as your local LINK to \n$FILE ?"
        echo "\nReturn to continue,anything else aborts."
        read ans
                if [ -n "$ans" ]
                then
                exit 1
                fi
        fi

        if [ -f $LINK ]
        then
        echo "bad bad bad boy, $LINK exists. If you don't believe me, look"
        ls -ld $LINK
        exit 1
        else
        echo "nice kitty"
        echo " $LINK is ready to create"
        fi

ln -s $FILE $LINK
echo "\n\n"
ls -ld $FILE $LINK | cut -c1-10,40-

echo "$0 : Completed"
# . End.mac
exit 0


+-----------------------------------------------------------------------------+
| karron@nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+

karron@MCIRPS2.MED.NYU.EDU (08/13/90)

I guess that you wrote tlink(1) ? It looks like you have done what I wanted to
do only did not think about it yet. Great!

You might want to get sgi to put a cross reference in the man page for link to
your tlink. That would clue us in to your good work.

Dangling links:

Here is how I get dangling links ...
cut-----------------------------------------------------------------------
#! /bin/sh
# run this below / so you don't hit your head
# on the root directory...
rm -rf D.DangleDirectory REAL_FILE
cd $HOME
mkdir D.DangleDirectory
echo "THE REAL FILE CONTENTS" > REAL_FILE
pwd
ln -s REAL_FILE D.DangleDirectory/SYMLINK
ls -l REAL_FILE
ls -l D.DangleDirectory/SYMLINK
cat D.DangleDirectory/SYMLINK
cd D.DangleDirectory
pwd
ls -l SYMLINK
cat SYMLINK
echo "try more qualified names"
cd $HOME
ln -s ./REAL_FILE ./D.DangleDirectory/SYMLINK1
ls -l REAL_FILE
ls -l ./D.DangleDirectory/SYMLINK1
cat ./D.DangleDirectory/SYMLINK1
cd D.DangleDirectory
pwd
ls -l ./SYMLINK1
cat ./SYMLINK1
echo "now try doing it the expected way"
cd $HOME
cd D.DangleDirectory
pwd
ln -s ../REAL_FILE SYMLINK2
ls -l ../REAL_FILE
ls -l SYMLINK2
cat SYMLINK2
echo "try fully qualified names"
cd $HOME
pwd
ln -s $HOME/REAL_FILE $HOME/D.DangleDirectory/QUALIFIED_LINK
ls -l $HOME/REAL_FILE
ls -l $HOME/D.DangleDirectory/QUALIFIED_LINK
cat $HOME/D.DangleDirectory/QUALIFIED_LINK
cd D.DangleDirectory
pwd
ls -l QUALIFIED_LINK
cat QUALIFIED_LINK
exit 0
cut-----------------------running the above will give you this-----------------
/karron
-rw-r--r--   1 root     mail          23 Aug 13 11:41 REAL_FILE
l---------   1 root     mail           9 Aug 13 11:41 D.DangleDirectory/SYMLINK
   -> REAL_FILE
cat: cannot open D.DangleDirectory/SYMLINK
/karron/D.DangleDirectory
l---------   1 root     mail           9 Aug 13 11:41 SYMLINK -> REAL_FILE
cat: cannot open SYMLINK
try more qualified names
-rw-r--r--   1 root     mail          23 Aug 13 11:41 REAL_FILE
l---------   1 root     mail          11 Aug 13 11:41 ./D.DangleDirectory/SYMLIN
   K1 -> ./REAL_FILE
cat: cannot open ./D.DangleDirectory/SYMLINK1
/karron/D.DangleDirectory
l---------   1 root     mail          11 Aug 13 11:41 ./SYMLINK1 -> ./REAL_FILE
cat: cannot open ./SYMLINK1
now try doing it the expected way
/karron/D.DangleDirectory
-rw-r--r--   1 root     mail          23 Aug 13 11:41 ../REAL_FILE
l---------   1 root     mail          12 Aug 13 11:41 SYMLINK2 -> ../REAL_FILE
THE REAL FILE CONTENTS
try fully qualified names
/karron
-rw-r--r--   1 root     mail          23 Aug 13 11:41 /karron/REAL_FILE
l---------   1 root     mail          17 Aug 13 11:41 /karron/D.DangleDirectory/
   QUALIFIED_LINK -> /karron/REAL_FILE
THE REAL FILE CONTENTS
/karron/D.DangleDirectory
l---------   1 root     mail          17 Aug 13 11:41 QUALIFIED_LINK -> /karron/
   REAL_FILE
THE REAL FILE CONTENTS
+-----------------------------------------------------------------------------+
| karron@nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+