How to find the directory of a running shell command

I want to distribute some Java software in a way that is easy to use. The software depends upon some libraries, so I need to set the class path before running Java. I created a simple command ile (for Unix and Windows) to launch the application. I assume the libraries are in the same irectory as the command file, but had a hard time finding out what directory the command file is in. I didn't want the user to have to set up a path or do anything to install: just expand a ZIP file and go.

Eventually I found an answer. Here are the two versions. I have tried it on debian, windows and cygwin. These commands run the class foo.Foo from the foo.Jar, which also uses lib/mail.jar.

-----------------foo.bat for Windows -------------

@ECHO OFF
set dir=%~dp0%
java -cp "%dir%/foo.jar;%dir%/lib/mail.jar" foo.Foo %1
---------------------------------------------------

I out to know what %~dp0% means, but I have to admit I don't. I'll look it up later.


------------------ foo.sh for Unix -------------------

#!/bin/bash
dir=`dirname $0`
os=`uname`
if test ${os:0:6} = "CYGWIN"
then
if test ${dir:1:8} = "cygdrive"
then
dir="${dir:10:1}:/${dir:12}"
fi
java -cp "$dir/foo.jar;$dir/lib/mail.jar" foo.Foo $*
else
java -cp "$dir/foo.jar:$dir/lib/mail.jar" foo.Foo $*
fi
---------------------------------------------------------

Make sure the line endings are correct, and the file has execute access.


Note that java has two kinds of separators for the class path depending on whether it is unix or windows. This by itself is pretty annoying, but it gets worse: when you run cygwin it is a unix OS but it uses the windows separator. Since dirname can return \cygdrive\c\... but this is not understood by Java, I have to change it to c:\... But Java seems to understand / or \ as the separator, which is good. Lots of fun!

I am not sure that these will work everywhere. But it is a start.
They work in these cases:

  • executing the command from an absolute path
  • executing the command via an alias
  • putting the directory on into your system PATH
Shouldn't this be easier?

No comments: