Wednesday, January 15, 2020

Which directory is that bash script in?

There may be times when you need to know the actual location a BASH script is located
within the script. This can be done with a combination of the $0 value and the dirname
command.

The $0 value

A BASH script makes the first command line argument available as $1, the second as $2
and so on. The command run, exactly as it was called but without the command line
arguments, is stored in $0

The dirname command

The dirname command returns the directory name part of a filename. Note that the directory
and/or file do not actually exists; dirname simply strips the last component of a file path.

For example, "dirname /a/b/c" will echo "/a/b", "dirname ../a/b/c" will echo "../a/b", "dirname
../" will echo "." and so on.

Putting it all together
The directory the BASH script is located can be retrieved using dirname $0 like so:

DIRECTORY=`dirname $0`

BUT note that this may be a relative path and not necessarily an absolute one, depending 
how the script is called. Take the following script, for example, which saves the directory
name to a variable for later use, and then echos it:

#!/bin/bash
DIRECTORY=`dirname $0`
echo $DIRECTORY
If the file is saved at /home/arun/bin/test1.sh, the permissions are changed so it can be
executed (chmod 0700 ~/bin/test1.sh) and it is run from /home/arun like so:

/home/arun/bin/test1.sh
then it will echo this:

/home/arun/bin
It it is run like so:

bin/test1.sh
then it will echo this:

bin
Because the path used to run the script in the second example is a relative path, "dirname
$0" only echo’s "bin", which may not be suitable.

Always return the absolute path

To always return the absolute path to the directory the script is located, change to the scripts
directory and get the dirname like so, again saving the value to a variable for later use and
then echoing it:

#!/bin/bash
DIRECTORY=$(cd `dirname $0` && pwd)
echo $DIRECTORY

If this script is saved as /home/arun/bin/test2.sh , then whether it is run as
/home/arun/bin/test2.sh or bin/test2.sh or by some other path, it will always echo:

/home/arun/bin

Note that although the change directory command (cd) is used, the script will not change
directory and any other calls within it are still relative to the current working directory.

If we were running the above script in /home/arun, then calling "pwd" in the next line would
still echo "/home/arun"