Baeldung Pro – Linux – NPI EA (cat = Baeldung on Linux)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Introduction

$PWD and $(pwd) refer to the current working directory, but they achieve this in different ways and belong to different categories. The former, $PWD, is an environment variable that automatically holds the absolute path of the current working directory. Meanwhile, the latter, $(pwd), is a command substitution that executes the pwd command, which prints the current working directory in the shell.

In this tutorial, we’ll explore when to use $PWD and $(pwd) with an understanding of the pros and cons. Furthermore, we’ll illustrate the usage with practical examples and real-world applications.

2. Understanding $PWD and $(pwd)

In shell scripting and command-line utilities, $PWD and $(pwd) are the two most common approaches for determining the current working directory. Both somewhat achieve the same outcome.

Understanding their differences is crucial for writing efficient and reliable scripts. We’ll explore each one in detail before discussing when to use them.

2.1. What Is $PWD?

The shell manages $PWD as a shell variable, which stores the current working directory. It typically reflects the path used to navigate to the directory, including symbolic links, rather than always storing the resolved absolute path.

For better understanding, we’ll create a folder and add a symbolic link to it. Then, we can determine the structure of the directory pathway based on how we navigate into the directory:

$ mkdir -p /home/$USER/projects
$ cd /home/$USER/projects
$ mkdir new_project
$ ln -s new_project current 
$ ls -l
total 4
lrwxrwxrwx 1 gbenga gbenga   11 Dec 15 17:52 current -> new_project
drwxrwxr-x 2 gbenga gbenga 4096 Dec 15 17:47 new_project

As shown in the illustration above, we created a directory named projects and moved inside the directory using cd. Subsequently, we created another directory named new_project and a symbolic link pointing to it. In addition, we verified the structure of the directory to confirm both the symbolic link and its target.

Now, let’s check the behavior of $PWD on both the new_project directory and the symbolic link.

First, we navigate to the new_project directory using the directory path. Then, we print out the $PWD environment variable storing the current directory:

$ cd
$ cd /home/$USER/projects/new_project
$ echo $PWD
/home/gbenga/projects/new_project

As shown in the result, the command printed out the absolute path, /home/gbenga/projects/new_project.

For comparison, let’s now navigate to the new_project directory using the symbolic link and print out the current path stored in $PWD:

$ cd 
$ cd /home/$USER/projects/current 
$ echo $PWD
/home/gbenga/projects/current

From the result, we can see that the output is different, as it captures how the user navigated to the new_project directory using the symbolic link. In cases like this, we can use the realpath “$PWD” command to get the absolute path:

$ realpath "$PWD"
/home/gbenga/projects/new_project

As the output shows, the command produces the real absolute path, regardless of how we got to the directory.

2.2. What Is $(pwd)?

$(pwd) is an example of command substitution that executes the pwd command and replaces $(pwd) with the command’s output. Unlike $PWD, the pwd command interacts directly with the operating system to fetch the current working directory.

Let’s use the previously created directory, new_project, to illustrate the output of $(pwd):

$ cd /home/$USER/projects/new_project/
$ echo "$(pwd)"
/home/gbenga/projects/new_project
$ cd /home/$USER/projects/current
$ echo "$(pwd)"
/home/gbenga/projects/current

Here, we tested both examples we’ve seen earlier to explore how $(pwd) handles absolute paths and symbolic links. Based on the result, both $(pwd) and $PWD handle symbolic and absolute paths in the same way.

However, $(pwd) has additional functionalities with its unique flags. The -P flag outputs the resolved absolute path, whereas the -L flag outputs the logical path, which may contain symbolic links. For example, let’s change the directory to new_project using the symbolic link and use echo $(pwd -P) to print its absolute path:

$ cd /home/$USER/projects/current 
$ echo "$(pwd -P)"
/home/gbenga/projects/new_project

As shown, $(pwd -P) resolves the symbolic path to an absolute path, and it’ll return the same if the original path is absolute.

3. When to Use Either $PWD or $(pwd)

Before we dive into when to use $PWD or $(pwd), we’ll highlight the major features of both methods for obtaining the current working directory.

3.1. Key Features of $PWD and $(pwd)

First, let’s observe the key features of $PWD:

  • Speed: It’s fast because its output is instantaneous as the variable is stored in memory. So, the shell doesn’t need to execute any commands.
  • Simplicity: It’s straightforward to use in scripts, especially for basic tasks like logging or path manipulation.

Next, let’s observe the key features of $(pwd):

  • Accuracy: It directly queries the system, so it’s less likely to be affected by any inconsistencies or unusual shell behavior.
  • Flexibility: It’s useful when we need the absolute directory path as part of a larger command or script logic.

Let’s illustrate the accuracy of $(pwd) when used in scripting as some shells allow users to manually change the value of $PWD. For illustration, we’ll create a simple script named changeCD.sh:

$ cat changeCD.sh
#!/bin/bash

# change Directory
cd /home/$USER/projects/new_project

# Assign path to PWD environment variable
PWD="/home/$USER/Documents"
echo "Modified \$PWD: $PWD"
echo "Value of \$(pwd): $(pwd)"

After creating the script, we use the chmod +x to make changeCD.sh executable. Then, we run the script:

$ sudo chmod +x changeCD.sh
$ ./changeCD.sh 
Modified $PWD: /home/gbenga/Documents
Value of $(pwd): /home/gbenga/projects/new_project

The result shows that $(pwd) is accurate, while the value of $PWD can be altered and can lead to a wrong conclusion.

3.2. Choosing $PWD or $(pwd)

It’s important to know why and when to use $PWD or $(pwd) to avoid inconsistency or breaking the code during execution. Based on the different concepts we’ve discussed, here’s a summary of when to use $PWD and $(pwd):

Requirements $PWD $(pwd)
Additional Notes
Performance
 

 

Yes

 

 

No

– Performance is critical, such as in loops or scripts.

$PWD is useful when the shell’s state accurately reflects the current directory.

Accuracy No  

Yes

– Accuracy is important when scripts interact with external processes that might alter the directory state.

$(pwd) is useful in cases of unusual shell configurations.

The performance advantage of $PWD lies in its speed. It’s optimal for scenarios where performance is critical, such as in loops.

On the other hand, $(pwd) excels in accuracy. It’s more reliable in dynamic or complex environments, especially when interacting with external processes or dealing with unusual shell configurations.

4. Conclusion

In this article, we examined when to use $PWD and $(pwd) by fully understanding both. So, while $PWD is faster and simpler, $(pwd) offers reliability in scenarios where accuracy is non-negotiable.

Understanding both allows users to make informed decisions and optimize scripts for efficiency and correctness.