When you develop complex Bash scripts and start putting various scripts into a folder, where one script interacts with another by, for example, starting it, it quickly becomes necessary to ensure we know the path the script was started from, so we can start the other scripts with a fully qualified pathname. This is important because the first script may have been started from outside the script’s directory. We could have also done so by using a relative path, so even – somehow – reading the command that started the current script will not work.
In this tutorial, you will learn:
- What the
pwd
command is, and what it does - How to discover from inside a Bash script what path that same script is in
Software requirements and conventions used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Linux Distribution-independent |
Software | Bash command line, Linux based system |
Other | Any utility which is not included in the Bash shell by default can be installed using sudo apt-get install utility-name (or yum install for RedHat based systems) |
Conventions | # – requires linux-commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires linux-commands to be executed as a regular non-privileged user |
What is pwd?
The pwd
command in Linux returns the Path Working Directory when executed. Whatever path we currently find ourselves in, and have previously navigated to (or have been placed into by our Operating System, like, for example, when we open a command prompt/terminal), will be what is return when we execute pwd
.
$ cd / $ pwd / $ cd /home $ pwd /home
Here, we changed to the root directory (/
) and executed pwd
. Our current path was the root directory, so /
is returned. We then changed to the /home
directory and executed pwd
again. The path returned is now /home
.
Inside a bash script, the pwd
command will work in the same way. It is also noteworthy to know that from within a Bash script (and on the command line outside of a Bash script also), we can use the special operating system variable ${PWD}
which will automatically be kept up-to-date by the operating system to contain our current path. This saves us from having to do something like calling a subshell, i.e. MYPATH="$(pwd)"
is not needed, we can simply invoke the ${PWD}
variable.
So we can use pwd, right?
Not exactly. Picture the following situation:
$ touch 'mypath.sh' $ echo '#!/bin/bash' >> mypath.sh $ echo 'echo ${PWD}' >> mypath.sh $ chmod +x mypath.sh
Here we defined a script named mypath.sh
and made it executable. Next, we jump up one directory from our home directory, and execute our script:
$ pwd /home/roel $ cd .. $ ./roel/mypath.sh /home
Whereas the pwd
command inside our mypath.sh
script is working correctly, there is a problem here: pwd
has returned the path we currently find ourselves in, namely /home
whereas the script is actually stored in the /home/roel
directory!
Remember the title of the article; we are looking for the path the script is stored in! So how can we find this?
The method!
Whereas there is no special variable in Bash to cover the path the script is stored in, there is a simple method to obtain it.
$ cd - /home/roel $ touch 'mypath2.sh' $ echo '#!/bin/bash' >> mypath2.sh $ echo 'MYPATH="$(cd "$(dirname \$0)" && pwd)"' >> mypath2.sh $ echo 'echo "${MYPATH}"' >> mypath2.sh $ chmod +x mypath2.sh
Here we defined a secondary script named mypath2.sh
. Within it we place a little special code ($(cd "$(dirname \$0)"; && pwd)
) which will find the path the script is in (by changing into it’s directory, based on the \$0
variable (which is the script name in the way we called it, i.e. using a potential relative or fully qualified path) and requesting the dirname for it (by reference, and note it can still be a relative path if the script was started using a relative path), and then changing into it (via the cd
) and subsequently requesting the pwd
(Path Working Directory) for the same, giving us the fully qualified path.
Let’s see if this works more correctly than only using pwd
:
$ cd .. $ pwd /home $ ./home/mypath2.sh /home/roel
The script works correctly, and even though mypath2.sh
was relatively called, from outside the directory of where the script resides, the output returned correctly reflected the information sought; the path where the script exists. We stored the same in the ${MYPATH}
variable, and this variable could now be used to for example call ${MYPATH}/someotherscript.sh
where someotherscript.sh
is another script in the same directory as mypath2.sh
Conclusion
In this article, we first look at pwd
and whether it would fulfill the problem at hand, finding out the path our script resides in, at all times. Whereas pwd
may work if we have not changed directories, it will not work correctly if we are outside of the path the script is in. We then introduced a small piece of code (MYPATH="$(cd "$(dirname \$0)" && pwd)"
which will always return the directory our script is in correctly.
A small piece of code, but a big solution for our Bash script coding issue! Enjoy
!