My desire is not to change directory then execute. I use a jar file and need to execute that. So I made a very basic shell script to do that.

java -jar TreeForm.jar

Then, I saved it as TreeForm, not TreeForm.sh. Next, I created a symbolic link as below:

ln -s /opt/TreeForm/TreeForm /usr/bin/
chmod +x /opt/TreeForm/TreeForm

It is successfully created. However, when I run, I take the error below from JAVA.

Error: Unable to access jarfile TreeForm.jar

So, it seems shell script does not run its own directory or does not look into that, but works in current directory. I don't really want to modify my script file giving full path of TreeForm.jar. So I wanted to ask, is there a way to find a file relative to script file without changing the current path or adding path to PATH variable? Or is there any variable having the path of script, not the current one?

3 Answers 3


The shell will not change to another directory unless you tell it to. If you want your script to execute commands in a different directory, call cd from your script.

The path to the script is available as "$0". If the script is a symbolic link, that's the path to the symbolic link. If you want to get the final target of the symbolic link, call realpath (available on most but not all modern unices; it's available on Linux (both GNU and BusyBox), FreeBSD and Solaris 11, but not OSX).

cd "$(dirname "$(realpath "$0")")"

realpath is a relatively recent addition to GNU coreutils; if your version is too old, you can use readlink -f which is older. For non-GNU systems, if realpath isn't present then readlink may be but it typically only looks through one level of symbolic links, most readlink implementations don't have the -f option to do the full resolution.

  • Working like a charm. The only thing is realpath is not built-in in Ubuntu 14.04. Thanks for edit and answer by the way. :)
    – Eray Erdin
    Mar 19, 2016 at 18:26
  • 2
    @ErayErdin Oh, I forgot realpath in GNU coreutils was that recent. You can use readlink -f instead. Mar 19, 2016 at 18:30
  • Now, it is perfectly fine. :)
    – Eray Erdin
    Mar 19, 2016 at 18:38

You can derive the director in which the shell script exists from its $0 parameter. For example, you might use dirnameto do this within the script:

cd $(dirname "$0")

That assumes that your jar-file is in the same directory where the script it.

If you want to reference the script via a symbolic link (and still, assuming that the script and jar-file are in the same directory), you could do this by a more complicated script that would

  • find the pathname for $0 (simple if you use the default $PATH lookup), and
  • use a program such as readlink to read the symbolic link. That isn't POSIX, but exists on many Linux systems.
  • if you don't have readlink, it's possible with other workarounds (including reading the output of ls).
  • however you read the link, cd to that location.

Further reading:

  • I tried that, unfortunately it did not work. :(
    – Eray Erdin
    Mar 19, 2016 at 18:10
  • Well, I debugged it, I printed out pwd. Since I created a symlink, it sees the script in /usr/bin directory. Is there another solution? :/
    – Eray Erdin
    Mar 19, 2016 at 18:12
  • It seems there is no way to get the path of original script. It seems it will always get the path of symlink. So I accept this as valid answer. | Thanks for help. :)
    – Eray Erdin
    Mar 19, 2016 at 18:17
  1. Remove the symlink
  2. Execute : PATH=$PATH:/opt/TreeForm/ then export PATH

To make change persistent add the command from 2nd point to your .bashrc file (in your user home directory). If you want it global (to all users) add it to /etc/bash.bashrc

  • 1
    I limited the solution in question as without changing the current path or adding path to PATH variable.
    – Eray Erdin
    Mar 19, 2016 at 18:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.