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
Short answer:
or (preferably):
$_ is worth mentioning as an alternative to $0. If you're running a script from bash, the accepted answer can be shortened to:
Note that this has to be the first statement in your script.
Use
dirname "$0"
:using
pwd
alone will not work if you are not running the script from the directory it is contained in.I've compared many of the answers given, and come up with some more compact solutions. These seem to handle all of the crazy edge cases that arise from your favorite combination of:
script
,bash script
,bash -c script
,source script
, or. script
If you're running from Linux, it seems that using the
proc
handle is the best solution to locate the fully resolved source of the currently running script (in an interactive session, the link points to the respective/dev/pts/X
):This has a small bit of ugliness to it, but the fix is compact and easy to understand. We aren't using bash primitives only, but I'm okay with that because
readlink
simplifies the task considerably. Theecho X
adds anX
to the end of the variable string so that any trailing whitespace in the filename doesn't get eaten, and the parameter substitution${VAR%X}
at the end of the line gets rid of theX
. Becausereadlink
adds a newline of its own (which would normally be eaten in the command substitution if not for our previous trickery), we have to get rid of that, too. This is most easily accomplished using the$''
quoting scheme, which lets us use escape sequences such as\n
to represent newlines (this is also how you can easily make deviously named directories and files).The above should cover your needs for locating the currently running script on Linux, but if you don't have the
proc
filesystem at your disposal, or if you're trying to locate the fully resolved path of some other file, then maybe you'll find the below code helpful. It's only a slight modification from the above one-liner. If you're playing around with strange directory/filenames, checking the output with bothls
andreadlink
is informative, asls
will output "simplified" paths, substituting?
for things like newlines.Works for all versions,including
source
" aka.
(dot) operator.$0
is modified from caller."./script"
"/full/path/to/script"
"/some/path/../../another/path/script"
"./some/folder/script"
Alternatively, if the bash script itself is a relative symlink you want to follow it and return the full path of the linked-to script:
SCRIPT_PATH
is given in full path, no matter how it is called.Just make sure you locate this at start of the script.
This comment and code Copyleft, selectable license under the GPL2.0 or later or CC-SA 3.0 (CreativeCommons Share Alike) or later. (c) 2008. All rights reserved. No warranty of any kind. You have been warned.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656
I would use something like this: