Search code examples
bashshell

Relative paths based on file location instead of current working directory


Given:

some.txt
dir
 |-cat.sh

With cat.sh having the content:

cat ../some.txt

Then running ./cat.sh inside dir works fine while running ./dir/cat.sh on the same level as dir does not. I expect this to be due to the different working directories. Is there an easy way to make the path ../some.txt relative to the location of cat.sh?


Solution

  • What you want to do is get the absolute path of the script (available via ${BASH_SOURCE[0]}) and then use this to get the parent directory and cd to it at the beginning of the script.

    #!/bin/bash
    parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
    
    cd "$parent_path"
    cat ../some.text
    

    This will make your shell script work independent of where you invoke it from. Each time you run it, it will be as if you were running ./cat.sh inside dir.

    Note that this script only works if you're invoking the script directly (i.e. not via a symlink), otherwise the finding the current location of the script gets a little more tricky)