Muffinresearch Labs by Stuart Colville

Bash: Resolving Symlinks to Shellscripts | Comments (3)

Posted in Code, Linux/Unix on 10th October 2008, 2:54 pm by Stuart

Here’s a way to resolve symlinks that call a bash shellscript.

The Problem

I like to be able to use something like this in my bash scripts:

SCRIPTDIR=$(dirname $0)

Which is great for a reference to where the script is, but it suffers from the problem that if you symlink to that script $0 now refers to the symlink rather than the actual script.

The Solution

The hack solution is to use the following instead:

function resolve_symlink {
    SCRIPT=$1 NEWSCRIPT=''
    until [ "$SCRIPT" = "$NEWSCRIPT" ]; do
        if [ "${SCRIPT:0:1}" = '.' ]; then SCRIPT=$PWD/$SCRIPT; fi
        cd $(dirname $SCRIPT)
        if [ ! "${SCRIPT:0:1}" = '.' ]; then SCRIPT=$(basename $SCRIPT); fi
        SCRIPT=${NEWSCRIPT:=$SCRIPT}
        NEWSCRIPT=$(ls -l $SCRIPT | awk '{ print $NF }')
    done
    if [ ! "${SCRIPT:0:1}" = '/' ]; then SCRIPT=$PWD/$SCRIPT; fi
    echo $(dirname $SCRIPT)
}
DIR=$(resolve_symlink $0)
echo $DIR

This updated version should fix the shortcomings of the previous version pointed out in the first comment by resolving links that are relative as well as link chains. Whilst readlink works for linux systems the script above should be portable across unixes which was the original intention.

If you can rely on python then there’s an even easier way:

DIR=$(python -c "import os; print os.path.realpath(\"${0}\")")
echo $DIR

But again portability is the key.

Find any issues or have improvements to add please let me know.

Post Tools

Comments: Add yours

1. On October 11th, 2008 at 6:50 am R Samuel Klatchko said:

Good first step, but I see at least two potential issues in it.

1) symlink chains (i.e. l2 symlinks to l1 symlinks to script). If the script is invoked as l2, you’ll get the directory of l1 instead of script.

2) relative symlinks. If the symlink is relative rather then absolute, the directory name you get needs to be interpreted relative to the symlinks directory.

2. On October 11th, 2008 at 10:17 am Stuart Colville said:

@R Samuel Klatchko: 2 very good points well made!

ON linux I’ve found that infact readlink -f $0 solves all the problems as it resolved relative paths and follows all the links correctly, the downside being mac’s don’t have gnu readlink by default! and the BSD equivalent has barely any functionality (That’s Reason no.343249 to look at moving to Ubuntu for me!)

However currently I’d ideally like a solution that works for Mac too. When I work out a portable solution I’ll update the post.

3. On October 12th, 2008 at 7:52 pm sil said:

heh. I just came to say: what’s wrong with readlink? Didn’t know it wasn’t on Macs. :)







XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Using Loggerhead with mod_wsgi|(0)

Here’s a post I wrote over on the Project Fondue Blog about our use of Loggerhead with mod_wsgi under Apache. Loggerhead is the rather nice branch viewer for bazaar branches as used on Launchpad.net.

If you’re not already subscribed to the Project Fondue blog feed then I can recommend it, as there should be some interesting posts coming out of there in the coming months (yes I’m unashamedly biased!).

Ubuntu: Turn off changing workspace with mouse wheel|(1)

I found the changing with the workspace with the mouse wheel really annoying. To disable it go to System => Preferences => CompizConfig (available if the compizconfig-settings-manager package is installed) and uncheck “Viewport Switcher” which is under the “Desktop” heading.

Photos on Flickr

© Copyright 2004-10 Stuart Colville, all rights reserved. May contain traces of Muffin. Powered by WordPress. Hosting by Slicehost.com This page was baked in 0.644s.