I need to write a script, which would be called from any location, but needs to run from the directory it resides in. The script should query its directory at runtime.

How can this be achieved?

Example:

  • script hello.sh resides in /someplace/
  • though it is called from /other/place/,
  • the script knows (during runtime) that it resides in /someplace

EDIT
Additional question:
How's about the location of the script, but with symlink resolved?

Example:

  • script hello.sh resides in /someplace/
  • symlink exists to it in /bin
  • though the symlink is called from /other/place/,
  • the script knows (during runtime) that it resides in /someplace
link|improve this question

I suggest you move this to Stackoverflow. I think it's more related to programming than to general computing, and you might get faster and better responses there. – Nathan Fellman Oct 1 '09 at 21:59
feedback

4 Answers

up vote 5 down vote accepted
echo $(dirname $0)

or

echo ${0%/*}
link|improve this answer
Great, it works! – linux_is_for_desktop Oct 1 '09 at 22:05
1  
Unless the script is in your PATH and you don't specify the full path to it; in that case, $0 will not have any path information. The best you can do then is to traverse PATH yourself. – wfaulk Oct 1 '09 at 22:08
"Unless the script is in your PATH" - I just tested this and got the correct result. The worst case is if you do ./scriptname then you just get back ., but you can test for that and get $PWD or $(pwd). – Dennis Williamson Oct 1 '09 at 22:18
Also, if you have readlink, you can do stuff like readlink -f .. to turn relative paths into absolute ones. – Dennis Williamson Oct 1 '09 at 22:20
feedback

To my additional question: I found this to work:

echo $(dirname $(readlink $0))

or

echo `dirname \`readlink $0\``

EDIT
Seems, this answer came at the same time Dennis Williamson commented his answer with the solution ;)

link|improve this answer
You can (and should) nest $(), so this would be echo $(dirname $(readlink $0)) – Dennis Williamson Oct 1 '09 at 22:22
Can you explain why, please? – linux_is_for_desktop Oct 1 '09 at 22:23
The second one would be parsed as echo dirname ` then readlink $0 then `` It has no way of knowing that the first should match the fourth `. With $( and ) it knows what matches what. – Randy Orrison Oct 1 '09 at 22:52
That mangled the backquotes. It should have been echo (backquote dirname backslash backquote) then (readlink $0) then (backquote backquote). It has no way of knowing that the first backquote should match the fourth backquote, so it just matches the first with the second, and the third with with fourth. – Randy Orrison Oct 1 '09 at 22:54
Readability, nestability, reduced need for escaping, etc.: mywiki.wooledge.org/BashFAQ/082 – Dennis Williamson Oct 2 '09 at 0:24
feedback

Wouldn't $0 have that information?

link|improve this answer
Ok, it gives me /long/path/hello.sh, but how do I get /long/path/ ? – linux_is_for_desktop Oct 1 '09 at 22:01
1  
dirname. as in "dirname /long/path/hello.sh" returns "/long/path" – quack quixote Oct 1 '09 at 22:14
feedback

Check out the shell variable $_

From the bash manpage:

At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file currently being checked.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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