Find Base Directory for a Application

The problem

When executing a application it is not uncommon that you need to be in that applications base directory so it can find its resource files. This is especially true when it comes to Java based applications and games on the Linux platform.

Some times this is just stated in the installations instructions and you have to change into the base directory before executing the binary that starts the application. My (not so humble) opinion is that this is not a acceptable solution. Mainly since I like to have a link to the application in a common directory such as /usr/local/bin/_ so I don’t have to change my PATH. Also I want to be able to start my applications from anywhere.

Simple and common solution

A simple and common solution for this is to create a shell script that gets the directory portion of the command executed and then switches into that directory before launching the application.

1
2
3
4
5
6
7
8
9
#!/bin/bash
# Startup script to launch the real application
#
BASEDIR=`dirname $0`
cd $BASEDIR
# Start the applikation
./app.real $@
# or in case of a java application
# $JAVA_HOME/bin/java -jar somefile.jar $@

The problem with this solution is that if you put this script (or a link to this script) in you PATH and then call it whitout the absolut path it will not find the correct basedir.

A better solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# Startup script to launch the real application
#
# First get the full path to the command executed
PROGPATH=`which $0`

# If the PROGPATH points to a symbolic link
# we have to resolve it
if [ -h $PROGPATH ]; then
  RESOLVED=`readlink $PROGPATH`
else
  RESOLVED=$PROGPATH
fi

# Now get the basedir
BASEDIR=`dirname $RESOLVED`
# Sometime you want the directory above the place where 
# the shell script are then use:
# BINDIR=`dirname $RESOLVED`
# BASEDIR=`dirname $BINDIR`

cd $BASEDIR
# Start the applikation
./app.real $@
# or in case of a java application
# $JAVA_HOME/bin/java -jar somefile.jar $@

If you put this script into the application base directory and then create a symbolic link in /usr/local/bin you can now start the application from anywhere just by executing app (provided this is the name of the shellscript).