DEV Community

Cover image for Set cwd to script directory
Adam K Dean
Adam K Dean

Posted on

Set cwd to script directory

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%/*}"
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (5)

Collapse
kogans profile image
Stanislav Kogan

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.

Collapse
adamkdean profile image
Adam K Dean Author

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.

Collapse
kogans profile image
Stanislav Kogan

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

Thread Thread
adamkdean profile image
Adam K Dean Author

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.

Collapse
yujiri8 profile image
Ryan Westlund

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)).