Linux & Bash · Part I · Module 2 · The Filesystem and Paths
Moving Around: cd, pwd and ls
Three chapters of model-building are enough to make this one easy. You already know what the tree looks like, how to write a path into it, and what the working directory does to a relative path. All that is left is the three commands that put the model to work: one to change where you are, one to ask where you are, and one to see what is there. The commands are small. What this chapter adds is the habit of moving deliberately — stating where you expect to land, going there, and checking — so that a surprising result becomes a question you can answer rather than a reason to start guessing.
Foundation15 min readLinuxBashPart IFundamentalsNavigation
Part I · Module 2 · Chapter 2.4 · Moving Around: cd, pwd and ls
1. What Each Command Is For
Three commands, three jobs, no overlap.
| Command | Job | What it changes |
|---|---|---|
pwd | report the working directory | nothing |
cd | change the working directory | the shell's own position |
ls | show what is in a directory | nothing |
Only one of the three changes anything, and what it changes is a single value inside your shell. That is worth holding on to: a session where you feel lost is a session where one number-sized piece of state drifted away from your mental picture of it, and pwd reads it back.
Chapter 1.7 established why cd must be a Bash builtin: it changes the shell's own state, and a separate program could only ever change its own copy. pwd is also a builtin. ls is an external program — a file on disk, as type ls would confirm.
That difference has a practical edge. Because ls is a separate program with its own author, its options and the exact look of its output vary between systems. cd behaves the same everywhere Bash does.
2. pwd — Ask, Do Not Assume
$ pwd
/home/engineer/projectIt takes no arguments in normal use and always answers with an absolute path.
The reason to run it often is Chapter 2.2: every relative path you type is completed from this value. If the value is not what you think, every relative path in the next command means something other than what you intended — and nothing on screen will warn you.
3. cd — Change Where You Are
cd takes one path and makes it the shell's new working directory. Every path form from Chapters 2.2 and 2.3 works, with no special cases.
With an absolute path
$ pwd
/home/engineer/project
$ cd /tmp
$ pwd
/tmpThe path started with /, so the old location played no part. This form works identically from anywhere.
With a relative path
$ cd /home/engineer/project
$ pwd
/home/engineer/project
$ cd rtl
$ pwd
/home/engineer/project/rtlrtl was resolved against /home/engineer/project, exactly as Chapter 2.2's rule says. Note that cd rtl from somewhere else would have meant something else entirely.
Up, with ..
$ pwd
/home/engineer/project/rtl
$ cd ..
$ pwd
/home/engineer/projectUp and over in one step
$ pwd
/home/engineer/project/sim
$ cd ../rtl
$ pwd
/home/engineer/project/rtlThis is the move you will make most often in a project: leave this directory, enter a sibling. It is one command because .. can sit in the middle of a path.
Home, with ~ or with nothing
$ pwd
/tmp
$ cd ~
$ pwd
/home/engineerAnd cd with no argument at all does the same thing:
$ pwd
/home/engineer/project/sim/logs
$ cd
$ pwd
/home/engineerThat is a deliberate convenience: a bare cd is the fastest way back to known ground from anywhere. It is worth building the reflex, because "I am somewhere confusing" is a situation that resolves instantly if you have one key that always means home.
Back where you were, with -
Chapter 2.3 warned that .. means up, not back. This is the one that means back:
$ pwd
/home/engineer/project/rtl
$ cd /tmp
$ pwd
/tmp
$ cd -
/home/engineer/project/rtl
$ pwd
/home/engineer/project/rtlcd - returns to the directory you were in immediately before the last cd. Notice that it also prints the directory it moved to — the only form of cd that prints anything, precisely because you did not type the destination and might want it confirmed.
It alternates. Running cd - again goes back again:
$ cd -
/tmp
$ cd -
/home/engineer/project/rtlThis is genuinely useful when you are working between two distant directories — a source directory and a results directory, say — and it saves retyping two long paths over and over.
4. ls — See What Is There
ls lists the entries in a directory. With no argument, it lists the working directory:
$ pwd
/home/engineer/project
$ ls
docs rtl scripts simFour entries, which matches the module's tree exactly.
Listing somewhere else, without going there
Give ls a path and it lists that path instead. You do not move:
$ pwd
/home/engineer/project
$ ls rtl
alu.sv counter.sv
$ pwd
/home/engineer/projectRead the three commands together: ls rtl showed the contents of /home/engineer/project/rtl, and the final pwd proves the shell never moved. ls looks; cd goes. Two different actions, easy to conflate when you are starting out.
This works with every path form:
$ ls /etc # absolute — anywhere on the machine
$ ls .. # the parent directory
$ ls ../rtl # a sibling directory
$ ls ~ # your home directoryBeing able to look without moving is more valuable than it first appears. Most of the time you want to check something — is the file there yet, did the directory get created — and checking without disturbing your position keeps your relative paths meaningful.
Listing more than one place
ls accepts several paths. When given more than one, it labels each:
$ pwd
/home/engineer/project
$ ls rtl scripts
rtl:
alu.sv counter.sv
scripts:
run.shThe labels appear only because there is more than one argument — with a single directory, ls prints the entries bare. This is the kind of per-program behaviour Chapter 1.5 warned about: it is ls's own choice, not a shell rule.
Two options you will meet immediately
Two options are so common they are worth recognising now, though each has its own chapter next:
$ ls -l # one entry per line, with details — Chapter 2.5
$ ls -a # include hidden entries — Chapter 2.6They are left for Chapter 2.5 and Chapter 2.6 rather than half-explained here.
5. Everything Else Follows Your Position
One point that is easy to miss when the commands are taken one at a time.
cd does not only move you. It changes the starting point for every relative path in every command you type afterwards — and for the programs those commands start, because Chapter 1.7 showed a child process inherits a copy of the working directory.
$ cd /home/engineer/project
$ ls rtl
alu.sv counter.sv
$ cd sim
$ ls rtl
ls: cannot access 'rtl': No such file or directoryNothing about ls changed between those two runs. The shell's position did, so the argument meant something different. This is Chapter 2.2's lesson arriving through a command instead of through a table, and it is the single most common way beginners confuse themselves.
6. A Full Walk Through the Project
Individual commands are easy; moving around is a sequence. Here is one, start to finish, with the tree to hand:
/home/engineer/project
├── docs
├── rtl
│ ├── alu.sv
│ └── counter.sv
├── scripts
│ └── run.sh
└── sim
└── logs$ cd ~
$ pwd
/home/engineer
$ ls
project
$ cd project
$ ls
docs rtl scripts sim
$ cd rtl
$ pwd
/home/engineer/project/rtl
$ ls
alu.sv counter.sv
$ cd ../sim
$ pwd
/home/engineer/project/sim
$ ls
logs
$ ls ../scripts
run.sh
$ cd ~
$ pwd
/home/engineerReading it as a story:
cd ~starts from known ground, whatever happened before.lsshows one entry,project— so the nextcdis safe.cd project, thenls— the habit of looking before moving again.cd rtluses a relative path that is correct because the previouslsconfirmed where we were.cd ../simgoes up and across in one step: out ofrtl, intosim.ls ../scriptslooks into a sibling without moving —pwdwould still saysim.cd ~returns to known ground at the end.
The pattern worth copying is look, move, confirm. It costs one extra command and removes nearly all navigation mistakes.
7. When It Goes Wrong
Four failures, each with a different cause and a different fix. Reading the message is most of the work.
The directory is not there
$ pwd
/home/engineer/project/sim
$ cd rtl
bash: cd: rtl: No such file or directoryThe prefix is bash: and then cd: — this is the builtin reporting, per Chapter 1.3. The path rtl resolved to /home/engineer/project/sim/rtl, which does not exist. The directory called rtl is real, but it is not there.
The fix is to say where it actually is:
$ cd ../rtl
$ pwd
/home/engineer/project/rtlThe name is a file, not a directory
$ cd /home/engineer/project/rtl/alu.sv
bash: cd: /home/engineer/project/rtl/alu.sv: Not a directoryA different message, and a useful one. The path was found — so this is not a typo — but it names a file, and you cannot be positioned inside a file. Seeing Not a directory rather than No such file or directory tells you your path was right and your expectation of what sits there was wrong.
A typo
$ cd /home/enginer/project
bash: cd: /home/enginer/project: No such file or directoryenginer instead of engineer. The same message as the first case, because to the system it is the same situation: nothing exists at the path given. When a path you are sure about fails, read it character by character before anything else — and recall that Chapter 1.8's history keys let you recall and edit the line instead of retyping it.
You are not allowed in
$ cd /root
bash: cd: /root: Permission deniedThe directory exists and you may not enter it. That is the system working correctly, not a fault to route around. Module 5 explains what grants and denies that access.
8. Why This Matters on a Real Machine
Chapter 1.4 had you orient on an unfamiliar machine with pwd, whoami and hostname. This chapter completes that routine: once you know where you are, ls tells you what is around you, and cd lets you explore without losing your place.
On a shared engineering machine the stakes are slightly higher than on a laptop, for one reason worth naming. Project directories are often deep, similar-looking, and duplicated per user or per revision — .../blockA/rev3/sim and .../blockA/rev4/sim differ by one character and contain the same file names. Nothing on screen distinguishes them except the prompt, and Chapter 1.4 established that the prompt is configurable text rather than evidence.
So the habit generalises: before any command whose effect you would not want applied to the wrong copy of something, run pwd. It is the same reflex as checking hostname before starting a heavy job — cheap, boring, and the reason some engineers never have that particular bad afternoon.
Part II returns to project layouts properly, once you have the search and scripting tools to work in them.
9. Practice
Use the module's tree and assume home is /home/engineer.
Question 1. You are in /home/engineer/project/docs. Write a single cd command that lands you in /home/engineer/project/sim/logs, using a relative path.
Question 2. You are in /home/engineer/project/sim/logs. Give two different single commands that land you in /home/engineer, and say which would still work if the tree were rearranged above project.
Question 3. You are in /home/engineer/project/rtl. You want to see what is in scripts without leaving rtl. Write the command, and say what pwd would print afterwards.
Question 4. cd sim prints bash: cd: sim: No such file or directory. List the two most likely causes and the one command you would run first to tell them apart.
Question 5. cd reports Not a directory. What does that tell you about whether your path was correct?
Question 6. You run cd with no argument. Where do you end up, and when is that more useful than cd ..?
Question 7. You are alternating between /home/engineer/project/rtl and /tmp. Which command saves you retyping both paths, and how many previous directories does it remember?
10. Remember
pwdreports,cdchanges,lsshows. Onlycdchanges anything, and what it changes is one value inside your shell.cdaccepts every path form from Chapters 2.2 and 2.3 — absolute, relative,..,~— with no special rules.cdwith no argument goes home.cd -returns to the previous directory and prints it...means up, not back.lslooks without moving.ls ../scriptstells you what is in a sibling directory while you stay where you are.- Changing directory changes every relative path you type next, including the ones inside programs you start.
- Look, move, confirm. One extra command removes most navigation errors.
- Read the failure message.
No such file or directory,Not a directoryandPermission deniedare three different facts about three different situations. - Colour in
lsoutput is a configured convenience, not dependable information. - Navigating a repository you did not write is a routine, not an exploration — Chapter 23.6 is eight commands in an order chosen so each one answers the most.
You can now move through the tree with intent. The next chapter stops at one directory and reads its contents properly — the long listing, and what each of its columns is telling you.
Where this fits
Part of the Linux & Bash curriculum.
