Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a utility consisting of a couple directories with some bash scripts and supporting files that will be deployed to several machines possibly in a different directory on each machine. The scripts need to be able to reference paths relative to themselves so I need to be able to get the path to the file that's currently being executed.

I am aware of the dirname $0 idiom which works perfectly when my script is called directly. Unfortunately there is a desire to be able to create symlinks to these scripts from a totally different directory and still have the relative pathing logic work.

An example of the overall driectory structure is as follows:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)

How can I reliably reference /usr/local/lib/foo/res/resource_file.txt from script.sh whether it is invoked by /usr/local/lib/foo/bin/script.sh or ~mike/bin/link_to_script?

share|improve this question

2 Answers 2

up vote 8 down vote accepted

Try this as a general purpose solution:

DIR="$(cd "$(dirname "$0")" && pwd)"

In the specific case of following symlinks, you could also do this:

DIR="$(dirname "$(readlink -f "$0")")"
share|improve this answer
    
Works perfectly and is way simpler than the stuff I was trying. Thanks! –  Mike Deck Jul 27 '11 at 20:19
    
@MikeDeck Enjoy. Note that I fixed some quoting issues since first posting ... you might use an option from the latest edit in the event that you have spaces or other wacky characters in your path sometime. Even if it doesn't matter for this project, you might copy the code from your own scripts down the road and having the best option matters then! –  Caleb Jul 27 '11 at 20:40
    
I should clarify, the second one works perfectly. The first solution you gave does not work for symlinks on my system. –  Mike Deck Jul 27 '11 at 20:47
    
@MikeDeck: The first solution works for the typical case of having various directories symlinked as part of the path, but won't help if the final binary is a symlink. That's what the second one manages to take care of. –  Caleb Jul 27 '11 at 21:19

one line:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
share|improve this answer
    
One line answers are typically not the most helpful. Please consider expanding your answer to include explanation, links or documentation which further support your suggested solution. –  HalosGhost Aug 29 at 2:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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