You typed `ls` and got a list you did not expect. Where are you, and how do you find out?
You open a terminal in the course project and type ls, which lists files. The names on screen match no tutorial you read. Nothing is broken: you stand in a different folder than the one you pictured, and the shell lists whatever surrounds it.
The shell is the text window where you type commands. Every command runs in a working directory, the folder the shell currently stands in. Almost every beginner surprise traces back to that fact: the command was fine, but the standing place was wrong.
Think of the working directory as the room you are standing in. When you name a file without saying where it lives, the shell looks in this room first. Two terminals can stand in different rooms, so the same command can give different answers in each one.
The command pwd prints the working directory: the full address of the room you are in. Make it a reflex. Whenever output surprises you, run pwd before you change anything, because many surprises end the moment you see the actual path.
Addresses come in two shapes. An absolute path starts at the root of the machine with /, for example /home/you/projects/mini-controller, and it names the same place from anywhere. A relative path starts from where you stand, for example rtl/mini_controller.sv, and it names a different file depending on the room. Two shortcuts keep relative paths short: . means this folder and .. means the folder above it. So cd rtl steps into the room below, and cd .. steps back out to the one above.
You need eight commands for everything this part of the course asks. The table below names each one with its job. Read the middle column as the contract: what you can count on each command to do.
Command | Job | Example |
|---|---|---|
| Prints the working directory |
|
| Lists all files, including hidden ones, with details |
|
| Creates folders, including parents, without complaint |
|
| Moves to another folder |
|
| Walks the tree below and names matches |
|
| Streams a file to the screen |
|
| Searches file contents, recursing into folders |
|
| Moves or renames a file |
|
Home paths in the transcripts below are shortened to /home/you/projects. On your machine the same commands print your own longer home path, and that difference is expected.
These eight commands are shell built-ins and core utilities, so no simulator version applies to them. They behave the same on macOS and Linux, and WSL is a Linux environment inside Windows. This course tested them on macOS and Ubuntu only. Native Windows shells such as Command Prompt and PowerShell are out of scope for this course: if you work on Windows, do the course inside WSL, where the shell is Linux.
The transcripts that follow assume the example project is already on your machine, which you get in the next lesson. To try the commands right now with nothing to download, build a throwaway folder, put a file in it, read the file back, and delete the whole thing. Nothing in it matters, so you cannot break anything.
# captured terminal output
$ mkdir sandbox
$ cd sandbox
$ pwd
/home/you/sandbox
$ echo "first note" > notes.txt
$ ls
notes.txt
$ cat notes.txt
first note
$ cd ..
$ rm -r sandbox
$ ls sandbox
ls: sandbox: No such file or directoryThe home path is shortened to /home/you; your pwd prints your own. The last line is the proof the delete worked: asking for the folder now fails. The wording of that error differs between macOS, which this run used, and Linux, but both say the folder does not exist.
The figure below shows the project tree once the transcript commands have run. Compare the two markers on the right: the standing place is the only thing that changes between them, and it changes what every relative path means.
The transcript below built the tree in the figure, one command at a time. Take the commands in order: each one assumes the standing place the previous one left behind.
# captured terminal output
$ pwd
/home/you/projects/shell/mini-controllerThe answer to the lesson question. pwd prints /home/you/projects/shell/mini-controller, and now you know which room the ls output came from.
# captured terminal output
$ ls -la
total 16
drwxr-xr-x 4 you users 128 Oct 21 18:24 .
drwxr-xr-x 3 you users 96 Oct 21 18:24 ..
-rw-r--r-- 1 you users 41 Oct 21 18:24 README.md
-rw-r--r-- 1 you users 555 Oct 21 18:24 mini_controller.svThe -l flag asks for details and -a asks for everything, including the . and .. entries and hidden files. The design file still sits beside README.md: no folders exist yet.
# captured terminal output
$ mkdir -p rtl tb docs scripts buildThis creates all five project folders at once. The -p flag stays silent if a folder already exists, so the command is safe to repeat. Silence here is success.
# captured terminal output
$ mv mini_controller.sv rtl/The design file moves into rtl/. From now on its address is rtl/mini_controller.sv from the project root, and the move is why the figure shows it nested.
# captured terminal output
$ find . -maxdepth 2 -type f | sort
./README.md
./rtl/mini_controller.svfind walks the tree below ., -type f keeps files only, -maxdepth 2 stops it descending further, and the pipe to sort orders the result. Two files exist, exactly where the move left them.
# captured terminal output
$ cat README.md
# mini-controller
A 4-bit event counter.cat streams the file to the screen: a title line and one sentence describing the 4-bit event counter. This is the whole file, and reading it costs one command.
# captured terminal output
$ grep -R "module mini_controller" rtl/
rtl/mini_controller.sv:module mini_controller (grep searches contents instead of names, -R recurses into folders, and the quotes hold the phrase together as one pattern. The answer rtl/mini_controller.sv:module mini_controller ( names the file and the matching line, which is how you find a definition without opening every file.
cd rtl && pwd && cd .. && pwd. What two lines print?First /home/you/projects/shell/mini-controller/rtl, then /home/you/projects/shell/mini-controller. The && chain runs each step only if the previous one succeeded, so the two pwd calls prove the round trip: down into rtl, then back out with ...
# captured terminal output
$ cd rtl && pwd && cd .. && pwd
/home/you/projects/shell/mini-controller/rtl
/home/you/projects/shell/mini-controllerThe transcript confirms it: the first line is the room inside rtl/, the second is the project root again. When a later lesson says run a command from the project root, this round trip is how you get back there.
Every command sends its normal output to stdout, the standard output stream, which a pipe | forwards to the next command. Error messages travel on a separate stream called stderr, standard error, so errors still reach your screen unsorted.
Every command also leaves behind an exit status. On macOS, Linux, and WSL alike, 0 means success and anything else means failure. The shell stores it in the variable $?, so typing echo $? right after a command shows you the status. There is no output to quote here: you read the number on your own screen the moment you try it.
Two habits follow. Chain dependent steps with &&, as the last transcript command does, so a failed step stops the chain. When a command fails silently, check $? before you rerun anything.
A path with a space in it breaks naive commands, because the shell splits arguments on spaces. The fix is quotes: cd "my projects/rtl" hands the shell one argument instead of two. The grep command above uses quotes for the same reason: they hold module mini_controller together as a single pattern. Quote any path you did not create yourself.
Deletion deserves a sterner paragraph. rm -rf removes a whole tree without asking and without an undo, and with a variable in place of the path a typo can aim it at the wrong tree. The course never asks you to run it outside a build folder, and never with a variable path. When generated files need clearing, the project Makefile does it: its clean target removes build/, which make recreates on the next run.
A relative path used from the wrong room. You type cat rtl/mini_controller.sv and get no such file, because you already stand inside rtl/. Run pwd and either step back with cd .. or use the absolute path.
An unquoted space. You type cd my projects and the shell sees two arguments. Quote the whole path: cd "my projects". Whenever a command complains about a path you can see exists, suspect the space first.
A folder treated as a file. You type cat rtl and get an error naming it a directory. Match the tool to the kind: ls rtl to look inside, cat for the files within.
Rule: know where you stand before you act: pwd first, relative paths second.
ls shows a listing you do not recognise. What are your first two commands, and why in that order?pwd first, then ls -la. The pwd output tells you which room the strange listing came from. Only then does a detailed listing help, because now you read it knowing where you are.
cd rtl twice in a row and the second run fails. What happened?The first cd rtl moved you into rtl/, so the second one looks for rtl/ inside rtl/ and finds nothing. Relative paths resolve from the new room every time. Step back with cd .. first, or check pwd before repeating a move.
grep -R "module mini" . prints nothing, but you are sure the design exists. Name two checks.First, pwd: confirm you stand at the project root, since the search covers only the tree below you. Second, the path argument: a wrong folder explains empty results better than a wrong pattern. Fix the standing place before doubting the design.
The shell always stands in a working directory; pwd shows it, and every relative path depends on it.
Eight commands cover the first project: pwd, ls, mkdir, cd, find, cat, grep, and mv, chained with && and piped with |.
Exit status 0 means success, quotes protect spaces, and deletion outside a build folder belongs to the Makefile, not your fingers.