1. Overview

For convenience, we might want to run a shell script that changes the folder we are currently in. If, for instance, we frequently visit the /var/log folder and want to navigate there quickly, we can create a Bash script to do that.

In this tutorial, we’ll have a look at how we can use the cd command to accomplish this. Along the way, we’ll see some of the intricacies of how cd behaves.

2. A Common Problem

Let’s begin with a script that begins by navigating to the /var/log directory. We’ll call it varlog.sh:

#!/usr/bin/env bash
# Filename: varlog.sh
cd /var/log
pwd
echo $$

The idea here is that we navigate to /var/log, display the current folder to verify that it has changed, and finally display the process ID of the shell it’s running in.

But, let’s understand the main limitation we’ll have when we run varlog.sh:

$ ./varlog.sh
/var/log
29903

As we can see, running our script gives us an output of /var/log as expected and the process ID of the shell.

Now, let’s see after executing the script, which folder we are currently in:

$ pwd
/home/baeldung

This is not what we were expecting as the current folder has not changed to /var/log. So, why did this happen?

Let’s check our shells process ID:

$ echo $$
28285

We can see that the process ID of the shell we’re in (PID 28285) and the process ID of the shell script (PID 29903) are different.

This implies that the Bash script is running in a separate independent shell. This separate shell terminates at the end of the script, leaving the parent shell, the shell we’re in, unaffected.

In the following sections, we’ll see several approaches to how we can overcome this problem.

3. Running Bash Scripts in the Same Process

To let the script run in the same process as our current shell, we can use the source command. This builtin command also has a short form using a . (dot).

First, let’s examine the help for the source command:

$ source --help
source: source filename [arguments]
Execute commands from a file <strong>in the current shell</strong>.
....

Great! So we can run a Bash script in the current process without starting a separate Bash process.

Let’s try that:

$ source varlog.sh
/var/log
28285

Let’s also verify that the folder we’re in has now changed:

$ pwd
/var/log

Nice! So we have demonstrated that using source, we can execute shell scripts in the current shell.

Alternatively, we could have used the short-form notation:

$ . varlog.sh
/var/log
28285

Note: If a Bash script is intended to be sourced rather than executed. It’s good practice to indicate with a comment such as # This file should be sourced at the top.

4. Bash Functions

Creating a Bash script for every folder is a pain. Instead, we could write several Bash functions within a single script:

# Filename: folders.sh
# This file should be sourced

function varlog() {
    cd "/var/log"
}

function tmp() {
    cd "/tmp"
}

Now if we source the file:

$ source folders.sh

We can use the functions within that script in our current terminal:

$ tmp
$ pwd
/tmp
$ varlog
$ pwd
/var/log

5. Aliases

We can further improve on our Bash functions by using the builtin alias command. An alias is more convenient to use than a function as it typically requires less typing.

Let’s try converting our functions into their alias variant:

# Filename: folders.sh
# This file should be sourced

alias varlog="cd /var/log"
alias tmp="cd /tmp"

We can see how concise this is, in comparison to the bash functions we wrote previously. In addition to that, we can use the alias in the same way as we have used the functions:

$ unset -f varlog
$ unset -f tmp
$ source folders.sh
$ varlog
$ pwd
/var/log
$ tmp
$ pwd
/tmp

In this sequence of commands, we’ve removed the functions from our environment using unset and replaced them with their equivalent alias. This is achieved by using source on folders.sh which contains the aliases.

For convenience, we could also do source folders.sh in our .bash_profile. This would allow the aliases to persist in our session.

6.  Using the z Utility

z is a utility that keeps a record of the most recent frequently visited folders. Instead of creating a Bash script, we can count on z to do the work for us automatically.

As z does not come pre-installed with Linux, we’ll need to install it. To install z download it and then source it in our .bashrc file:

source <location of z>/z.sh

To try this out, let’s start navigating through different folders using cd:

$ cd ~/Downloads
$ cd ~/Music
$ cd /var/log
$ cd ~
$ z
29859      /home/user/Music
29868      /var/log
59694      /home/user/Downloads

Notice how after invoking z we get a list of the folders we’ve visited. To go to a specific folder without having to type in the full path, let’s try using z instead of cd.

$ cd ~
$ z log
$ pwd
/var/log

We can see that navigating to a specific location is much quicker as the whole path does not need to be typed. By typing in z log, z was able to cd into /var/log.  This is because this is the most frequently visited directory matching log.

7. Conclusion

In this tutorial, we’ve seen several ways of using the cd command from within Bash. First, we learned that running a shell script directly executes in its own independent process.

To overcome this, we experimented with the source command which lets us execute shell scripts in the current process. Then, we took a look at improving our Bash scripts by using functions and the alias command. Finally, we looked at a utility called z, which allows us to navigate to different folders very quickly.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.