Linux command: pwd
Every shell session starts you somewhere in the filesystem, and almost every command you run depends on where that "somewhere" is. pwd is the command that answers the simplest question in Linux: where am I right now? It looks like the most boring tool on the system, yet behind those three letters sits a small surprise about how the kernel really tracks your position, and why two versions of pwd can disagree about the very same directory.
1. The Basics
The job of pwd is to print your current working directory: the folder your shell is standing in right now. Every relative path you type is measured from this spot. When you run ls, cat notes.txt, or ./build.sh, the shell starts looking from your current directory. pwd tells you exactly where that starting point is.
Two ideas make pwd more interesting than it first appears. First, the current directory is per process. It is not a global setting for the whole machine; every running program has its own, quietly inherited from the program that started it. pwd reports the one your shell happens to hold. Second, the kernel does not store your location as a piece of text like /home/peter. It stores a direct pointer to the directory itself. The readable path is something that has to be worked out, and section 6 shows why that matters.
The command that answers "where am I?" in three letters, and quietly reveals that your location is a live link into the filesystem, not just a string.
This article starts with the simplest possible use and builds up to logical versus physical paths, the difference between the shell builtin and the standalone program, and the strange things that happen when the directory under your feet disappears.
Back to topThe right mental model: the kernel remembers which directory you are in, not what it is called.
pwdturns that position back into a name you can read.
2. Where the Name Comes From
The name pwd is short for print working directory.
pwd = Print Working Directory
Like most early Unix commands, it was made short on purpose. Early Unix was typed on slow teletype terminals that printed each character onto paper, so short names saved both time and ink. That is why so many core commands are two or three letters: ls (list), cp (copy), mv (move), cd (change directory), and pwd (print working directory).
The word "print" here means "print to the screen", which in the teletype era literally meant printing onto paper. Today it just writes one line to your terminal, but the name has never changed.
Back to top3. A Short History
The idea of a current working directory was one of the innovations of the original Unix at Bell Labs in the early 1970s. Once a filesystem became a tree of directories, you needed a way to "be somewhere" in that tree and to ask where that was. pwd has been a standard Unix utility ever since, and it is defined by the POSIX standard that modern systems follow.
| Era | Milestone |
|---|---|
| Early 1970s | Unix introduces the hierarchical filesystem and the working-directory concept |
| Classic Unix | pwd works out the path by walking up the tree through .. |
| POSIX era | pwd is standardised, with the -L (logical) and -P (physical) options |
| Today | Linux answers the lookup directly through the getcwd() system call; a shell builtin and a coreutils program both exist |
One detail matters for everything that follows. On a typical Linux system there are two versions of pwd. Your shell (Bash, Zsh, and others) has pwd built in, and the GNU coreutils package ships a separate program at /bin/pwd. They look identical, but their defaults differ. Section 6 explains how, and why it can bite you.
4. Simple Use Cases
4.1 The Simplest Possible Use
Type pwd with nothing after it. It prints one line: the full, absolute path of where you are. In the example below, the line that starts with $ is what you type, and the line under it is what the system prints back.
$ pwd
/home/peter/projects/website
The path always starts from the root / and is absolute, so it is never ambiguous. Wherever you paste that line, it means the same directory.
4.2 The First Thing to Type on a Strange Server
When you log in to an unfamiliar machine over SSH, or when a script has left you somewhere unexpected, pwd is the safe first move. It only reads; it changes nothing. Paired with ls and whoami, it answers the three questions that orient you instantly.
$ whoami
peter
$ pwd
/var/www/example.com
$ ls
config logs public_html
Together these say: I am the user peter, standing in the site's web root, and here is what it contains. Now you know it is safe to act.
4.3 The $PWD Variable
The shell also keeps your current directory in a variable called $PWD. Most of the time echo "$PWD" and pwd print the same thing.
$ echo "$PWD"
/home/peter/projects/website
The shell keeps a companion variable too: $OLDPWD holds the directory you were in before the last cd. It is the value that powers cd -, the "jump back" shortcut.
$ cd /etc
$ cd /var
$ echo "$OLDPWD"
/etc
The difference is that $PWD is a string the shell stores and trusts, while pwd can be asked to check the real filesystem. That gap is small, but it is exactly where the surprises in section 7 come from.
4.4 pwd Inside Your Prompt
You rarely type pwd as often as you might expect, because most shells already show a shortened form of the current directory in the prompt itself. In Bash the special code \w puts the working directory into your prompt string $PS1.
$ PS1='\u@\h:\w\$ '
peter@server:~/projects/website$
Here \w is the working directory (with your home shown as ~), \u is the user, and \h is the hostname. When your prompt already shows where you are, pwd becomes the tool you reach for inside scripts and when the prompt is hidden.
5. Moderate Use Cases
5.1 Using pwd in Scripts
Inside a script, pwd lets you record where you started so you can return later, or build absolute paths from a relative starting point.
$ start="$(pwd)" # remember where we are
$ cd /tmp/build
$ # ... do some work ...
$ cd "$start" # come back to the exact spot
Capturing the output with $( ... ) stores the single line that pwd prints into a variable. This is a common, reliable pattern, though for the directory a script itself lives in, most authors prefer "$(dirname "$0")", because pwd reports where the script was run from, not where it is stored.
5.2 Symbolic Links Complicate "Where Am I?"
A symbolic link (symlink) is a directory entry that points at another location. They make one folder appear inside another, which raises a real question: if you followed a symlink to get here, should pwd report the path you typed, or the real folder on disk?
Both answers are useful, so pwd supports both through two options: -L for the logical path and -P for the physical path.
$ ln -s /var/www/html site # "site" is a link to /var/www/html
$ cd site
$ pwd
/home/peter/site # the path you followed
You stand in what looks like /home/peter/site, but the real files live in /var/www/html. The next section shows how to ask for each answer on purpose.
5.3 Logical Paths: -L
The -L option (short for logical) tells pwd to report the path as you reached it, symlinks and all. It keeps the name that matches how you navigated, which is usually what a human wants to see.
$ pwd -L
/home/peter/site # keeps the symlink in the path
For the shell builtin, -L is simply the default: it prints the value of $PWD, the path the shell has been remembering as you moved around.
5.4 Physical Paths: -P
The -P option (short for physical) does the opposite. It resolves every symlink and prints the real location on disk. Reach for it when you care about the true path, for example before a backup, a permissions change, or anything that must not be fooled by a link.
$ pwd -P
/var/www/html # the real directory, links resolved
Back to topLogical is "the path I took"; physical is "the path that is really there". Most of the time you want logical, because it matches how you got where you are. Use physical when the truth on disk matters more than the route you walked.
6. Advanced Use Cases
6.1 The Builtin and the Program Disagree
Here is the fact that trips up even experienced users. There are two pwd commands, and their defaults are opposite. Confirm it for yourself:
$ type pwd
pwd is a shell builtin
$ which pwd
/bin/pwd
When you type pwd, you get the shell builtin, whose default is logical (-L). The separate program at /bin/pwd, from GNU coreutils, defaults to physical (-P). Stand in a symlinked directory and the two print different paths for the same spot:
$ cd /home/peter/site # a symlink to /var/www/html
$ pwd # the builtin: logical by default
/home/peter/site
$ /bin/pwd # the program: physical by default
/var/www/html
Neither is wrong; they answer different questions. But if a script calls /bin/pwd expecting the same output as an interactive pwd, the mismatch can cause real, hard-to-find bugs. When it matters, be explicit and always pass -L or -P yourself instead of relying on the default.
6.2 How pwd Finds the Path at All
Recall the mental model from section 1: the kernel stores your position as a pointer to a directory, not as a string. So how does a physical pwd turn that pointer back into text like /var/www/html?
The classic method is to walk up the tree. Every directory contains an entry called .. that points to its parent. Starting from where you are, pwd looks at the parent, finds the name that leads back to the current directory, remembers it, then repeats one level higher, all the way to the root /. Reversing that list of names gives the full path.
current dir -- .. --> parent (find my name here: "html")
parent -- .. --> /var/www (find its name: "www")
/var/www -- .. --> /var (find its name: "var")
/var -- .. --> / (reached the root)
read the names in reverse: / + var + www + html = /var/www/html
Modern Linux makes this fast with a single system call, getcwd(), so the shell rarely walks the tree by hand any more. But the old idea still explains the behaviour, especially the failure you will see in the next section. The logical builtin skips all of this: it just prints the string it has been keeping in $PWD, which is why it is instant and why it can sometimes be out of date.
The same getcwd() call is what every programming language reaches for under the hood. This is why "print the working directory" looks almost identical whatever tool you use:
char *getcwd(char *buf, size_t size); // C, the underlying call
os.getcwd() # Python
getcwd(); // PHP
The command pwd is really just a thin wrapper around this one kernel service.
6.3 Keeping $PWD and Reality in Sync
Because the logical answer comes from a stored string, it is only correct as long as the shell keeps that string up to date. The shell does this for you every time you use cd. Trouble appears when something moves the directory underneath you without the shell knowing, which is exactly the case in the next section.
7. Something Most Users Do Not Know
7.1 pwd Can Lie After a Directory Is Deleted or Renamed
This is the detail that makes pwd genuinely interesting. Your shell is sitting in a directory, and from another terminal someone deletes it. You are now standing in a folder that no longer has a name on disk. Watch how the two versions of pwd react completely differently:
$ cd /tmp/work
$ rmdir /tmp/work # removed from another terminal
$ pwd # the builtin: still trusts $PWD
/tmp/work
$ /bin/pwd # the program: tries to walk the tree, and fails
/bin/pwd: couldn't find directory entry in '..' with matching i-node
Both answers are "correct" in their own way. The logical builtin prints the string it remembers, so it happily reports the old path even though it is gone. The physical program tries to reconstruct the path from the real filesystem, but the directory it needs is no longer listed in its parent, so it cannot, and it says so plainly. This one example demonstrates, better than any explanation, that logical pwd reads a memory of where you were, while physical pwd checks where you actually are.
The same thing happens if the directory is renamed or moved while you sit in it. The builtin keeps showing the old name; the physical version shows the new true path (or fails if the folder is gone). The cure is always simple: cd somewhere that still exists, such as cd ~, and your $PWD is fresh again.
7.2 There Is Almost Never a Reason to Type the Full Path Twice
Because pwd prints a clean, absolute path, it pairs beautifully with copy and paste and with command substitution. Instead of retyping a long path, capture it once.
$ cd /very/deep/project/config/nginx
$ here="$(pwd)" # grab it once
$ tar -czf backup.tgz "$here"
Small habit, real time saved: whenever you are about to type a long absolute path that you are already standing in, let pwd produce it for you.
7.3 pwd Is Where a Relative Path Begins
Every relative path in Linux is silently prefixed with your current directory. The name config.php really means "config.php inside whatever pwd reports". Seeing it this way removes a lot of confusion: a script that "cannot find a file" is very often simply being run from a different directory than you assumed. Running pwd as the first debugging step turns a mystery into an obvious answer.
7.4 The Root Directory Is Its Own Parent
The tree-walk in section 6.2 climbs from parent to parent until it reaches the root /. But what stops it there? The answer is a small, elegant trick built into the filesystem: the root directory is its own parent. The .. entry inside / points straight back at /.
$ cd /
$ pwd
/
$ cd .. # "up" from the root...
$ pwd
/ # ...still the root
You can type cd .. at the root all day and never go anywhere. This is exactly why the walk in section 6.2 knows when to stop: it keeps climbing until a directory's parent is itself, and that directory can only be /. A neat detail that turns "where does the filesystem end?" into a one-line answer.
8. Best Practices
- Run
pwdthe moment you feel lost. On a strange server, or when a command behaves oddly, confirm where you are before you act. It is read-only and cannot break anything. - Be explicit about
-Land-Pwhen it matters. Do not rely on the default in scripts. If you need the real location, writepwd -P; if you need the path as navigated, writepwd -L. - Remember that
pwdand/bin/pwddefault differently. The builtin is logical, the coreutils program is physical. A script that mixes them can compare two paths that were never meant to match. - Capture the path with
"$(pwd)", always quoted. Quoting protects paths that contain spaces, which are common on real systems. - If
pwdlooks stale, justcdagain. After a directory is moved or removed under you, a freshcdto a real path resets$PWD. - Reach for the documentation. Because there are two versions, they document in two places.
$ help pwd # the built-in version (Bash)
$ man pwd # the coreutils program at /bin/pwd
$ pwd --help # a quick option summary from the program
Note that help pwd describes the builtin your shell actually runs, while man pwd describes /bin/pwd. When their behaviour differs, read the one that matches the command you are calling.
9. Common Mistakes
9.1 Three Common Myths
| Myth | Reality |
|---|---|
"pwd always reads the real filesystem." |
The default builtin is logical: it prints the stored $PWD string, which can be out of date. |
"pwd and /bin/pwd are the same command." |
One is a shell builtin (logical by default), the other a coreutils program (physical by default). |
"The path pwd shows is the real path on disk." |
Through a symlink it shows the route you took. Use pwd -P for the true location. |
9.2 Other Traps to Avoid
- Trusting a stale path after a move. If a directory is renamed or deleted while you are in it, the logical
pwdkeeps showing the old name. Runcd ~to reset, or usepwd -Pto see the truth. - Assuming a symlinked path and the real path are interchangeable. Scripts that compare paths can fail when one side is logical and the other physical. Pick one form with
-Lor-Pand use it consistently. - Forgetting to quote
"$(pwd)". An unquoted path that contains a space splits into several arguments and breaks the command. - Expecting
pwdto show where a script lives. It shows where the script was run from. For the script's own location, use"$(dirname "$0")". - Confusing
pwdwithcd.pwdonly reports your location; it never moves you. To change directory you needcd.
10. Summary
The pwd command looks trivial, but it is a clear window into how Linux tracks your place in the filesystem.
pwdmeans "print working directory". It prints the absolute path of the folder your shell is standing in.- The current directory is per process and is stored by the kernel as a pointer to a directory, not as a piece of text.
pwdturns that pointer back into a readable path. -L(logical, the default builtin) shows the path as you navigated it, symlinks kept.-P(physical) resolves symlinks to the real location.- There are two versions: the shell builtin (logical by default) and
/bin/pwdfrom coreutils (physical by default). Their defaults are opposite. - The logical answer comes from the
$PWDstring, so it can be stale; the physical answer is rebuilt from the filesystem and fails if the directory has been removed. - If a folder is moved or deleted under you,
pwdcan show an old name. A freshcdfixes it. - Documentation lives in two places:
help pwdfor the builtin,man pwdfor the program.
This is the quick reference worth keeping:
pwd print the current directory (logical, as navigated)
pwd -L force the logical path (keep symlinks)
pwd -P force the physical path (resolve symlinks)
/bin/pwd the coreutils program (physical by default)
echo "$PWD" the shell's stored copy of the path
here=$(pwd) capture the path into a variable
help pwd built-in manual (Bash)
man pwd manual for /bin/pwd
Small commands like pwd hide a surprising amount of how Linux is built, from per-process state to the difference between a name and a real location on disk. If your servers behave in ways that are hard to explain, or you want a setup that is easier to run day to day, it often pays to look closely at these fundamentals. That is exactly the kind of work I enjoy helping with.


Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.


