Cover image for Set cwd to script directory

Set cwd to script directory

adamkdean profile image Adam K Dean ・1 min read

Perhaps this will be the smallest snippet I've ever posted, and yet, one of the most useful. If you have a script that you want to be able to invoke from anywhere and yet not worry about relative paths, use this.

cd "${0%/*}"

This works great when you have a script in a subdirectory that builds a dockerfile, and you want it to look for the relative Dockerfile.


Editor guide

Generally, it is a good idea to avoid "cd" in scripts. The problem is, that there is no guarantee that the directory will still be there after you cd'ed into it. Be a Jedi and use absolute paths unless you have no choice.


The above takes that into account, and sets the path to the location of the script at runtime. Simply, it negates the above risk without requiring the rigidity of absolute paths.


In this specific case, you are correct.
My comment was more of a general nature.

Oh absolutely. Using cd in a script is general not recommended due to the very nature of relative paths. If you don't know where you are, how can you know where to go? Like when you drop out of hyperspace unexpectedly, if you don't know where you are, you can't get home!

The beauty of the snippet above cd "${0%/*}" is ${0%/*} which takes the filename of the script, e.g. /home/bin/script.sh and discards everything after the last slash to give you the path, which you change directory into.

Which means you can negate not knowing where you executed the script from, and suddenly, you're able to use relative paths, such as the implicit relative Dockerfile expected by docker build.


Wow, I wouldn't have thought of this! Pretty cool, although it won't work in my shell :XD In fish the alternative seems to be cd (dirname (status -f)).