How can I set the current working directory to the directory of the script in Bash? How can I set the current working directory to the directory of the script in Bash? bash bash

How can I set the current working directory to the directory of the script in Bash?


#!/bin/bashcd "$(dirname "$0")"


The following also works:

cd "${0%/*}"

The syntax is thoroughly described in this StackOverflow answer.


Try the following simple one-liners:


For all UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

Bash

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

Note: A double dash (--) is used in commands to signify the end of command options, so files containing dashes or other special characters won't break the command.

Note: In Bash, use ${BASH_SOURCE[0]} in favor of $0, otherwise the path can break when sourcing it (source/.).


For Linux, Mac and other *BSD:

cd "$(dirname "$(realpath "$0")")";

Note: realpath should be installed in the most popular Linux distribution by default (like Ubuntu), but in some it can be missing, so you have to install it.

Note: If you're using Bash, use ${BASH_SOURCE[0]} in favor of $0, otherwise the path can break when sourcing it (source/.).

Otherwise you could try something like that (it will use the first existing tool):

cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"

For Linux specific:

cd "$(dirname "$(readlink -f "$0")")"

Using GNU readlink on *BSD/Mac:

cd "$(dirname "$(greadlink -f "$0")")"

Note: You need to have coreutils installed(e.g. 1. Install Homebrew, 2. brew install coreutils).


In bash

In bash you can use Parameter Expansions to achieve that, like:

cd "${0%/*}"

but it doesn't work if the script is run from the same directory.

Alternatively you can define the following function in bash:

realpath () {  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"}

This function takes 1 argument. If argument has already absolute path, print it as it is, otherwise print $PWD variable + filename argument (without ./ prefix).

or here is the version taken from Debian .bashrc file:

function realpath(){    f=$@    if [ -d "$f" ]; then        base=""        dir="$f"    else        base="/$(basename "$f")"        dir=$(dirname "$f")    fi    dir=$(cd "$dir" && /bin/pwd)    echo "$dir$base"}

Related:

See also:

How can I get the behavior of GNU's readlink -f on a Mac?