How do I get the path of the directory in which a Bash script is located, inside that script?
For instance, let's say I want to use a Bash script as a launcher for another application. I want to change the working directory to the one where the Bash script is located, so I can operate on the files in that directory, like so:
$ ./application
The dirname command is the most basic, simply parsing the path up to the filename off of the $0 (script name) variable:
But, as matt b pointed out, the path returned is different depending on how the script is called. pwd doesn't do the job because that only tells you what the current directory is, not what directory the script resides in. Additionally, if a symbolic link to a script is executed, you're going to get a (probably relative) path to where the link resides, not the actual script.
Some others have mentioned the readlink command, but at its simplest, you can use:
readlink will resolve the script path to an absolute path from the root of the filesystem. So, any paths containing single or double dots, tildes and/or symbolic links will be resolved to a full path.
Here's a script demonstrating each of these, whatdir.sh:
Running this script in my home dir, using a relative path:
Again, but using the full path to the script:
Now changing directories:
And finally using a symbolic link to execute the script:
This gets the current working directory on Mac OS X 10.6.6:
Hmm, if in the path basename & dirname are just not going to cut it and walking the path is hard (what if parent didn't export PATH!). However, the shell has to have an open handle to its script, and in bash the handle is #255.
works for me.
Try the following cross-compatible solution:
as
realpath
orreadlink
commands are not always available (depending on the operating system) and${BASH_SOURCE[0]}
is available only in bash shell.Alternatively you can try the following function in bash:
This function takes 1 argument. If argument has already absolute path, print it as it is, otherwise print
$PWD
variable + filename argument (without./
prefix).Related:
This works in bash-3.2:
Here's an example of its usage:
Say you have a ~/bin directory, which is in your $PATH. You have script A inside this directory. It sources script ~/bin/lib/B. You know where the included script is relative to the original one (the subdirectory lib), but not where it is relative to the user's current directory.
This is solved by the following (inside A):
It doesn't matter where the user is or how he calls the script, this will always work.
Try using: