Basic Linux commands — theory with your IC2 folder, paths that get lost and an rm that doesn’t forgive (and the folder that “vanished” on day one)
On the first day of IC2 labs I opened the Fedora terminal, typed the most innocent command in the world and Linux answered with an error:
$ cd Practices bash: cd: Practices: No such file or directory $ pwd /home/sergio $ ls Descargas Documentos Escritorio IC2 $ cd IC2/Practices $ pwd /home/sergio/IC2/Practices
I spent ten minutes convinced that my labs folder had been deleted. Nothing had been deleted: I was in my home folder and Practices lived inside IC2. Two commands, pwd and ls, were enough to see it. That’s exactly what this article is about: always knowing where you are, what’s around you and how to move, create, copy and delete without fear.
Today you’ll learn the basic Linux commands you’ll use in every IC2 lab: pwd, ls, cd, mkdir, rmdir, touch, cat, cp, mv, rm and the help you get from --help and man. If you don’t have Linux yet, start with Linux for students, install Fedora on VirtualBox and set up the shared folder with Windows. When you finish, the basic commands practice is waiting for you.
Table of Contents
How to read a terminal command
Every command in this article has the same shape: command, options and arguments, separated by spaces.
| Part | What it is | Example in ls -l IC2 |
|---|---|---|
| Command | The program you want to run | ls |
| Options | Letters with a dash that change its behaviour | -l (long format) |
| Arguments | What it works on: files, folders, paths | IC2 |
Three details that save you a lot of mistakes:
- Spaces separate the pieces.
ls -l IC2is three pieces;ls -lIC2is one strange option. That’s why a name with spaces (My practices) causes trouble, as you’ll see in the exercises. - Single-letter options can be combined:
ls -l -aandls -laare the same thing. - Linux is case-sensitive everywhere:
IC2andic2are two different names, andls -Lis notls -l.
The outputs in this article are real: I ran them once in a terminal as the user sergio. On your computer you’ll see your own user, group and date. My Fedora is set up in Spanish, so the default folders are called Descargas, Documentos and Escritorio; on an English system they’re Downloads, Documents and Desktop. Also, ls arranges names in columns in your terminal; here they appear one per line because the output was saved to a file. The list is the same.
pwd: where am I?
pwd (print working directory) prints the working directory: the place from which all your commands are interpreted. It’s the first thing to check when something “doesn’t exist”.
# pwd (print working directory): the folder I am in right now pwd cd Documentos pwd # cd with nothing after it takes me back to my home folder cd pwd
When you run it, the terminal shows this:
$ pwd /home/sergio $ cd Documentos $ pwd /home/sergio/Documentos $ cd $ pwd /home/sergio
Notice three things:
- When you open the terminal you always start in your home folder,
/home/sergio(for you,/home/your-user). - After
cd Documentos,pwdchanges: any path you type is now read fromDocumentos. cdwith no arguments takes you home. It’s the terminal’s “home button”.
If a command tells you “No such file or directory”, before thinking something has been deleted, type pwd and ls. Nine times out of ten you’re in a different folder.
ls: what’s here
ls (list) shows the contents of a folder. On its own it lists the current folder; with an argument, the one you name. Its options are the ones you’ll use most in the whole course:
# plain ls: the names of what is in the current folder ls # -a (all): hidden ones too, the ones starting with a dot ls -a # -l (long): one line per item with type, permissions, owner, size and date ls -l # options can be combined: -la = -l + -a ls -la # -h (human): sizes in K, M, G instead of bytes; only makes sense with -l ls -lh lecture.pdf
And the real output:
$ ls Descargas Documentos Escritorio IC2 lecture.pdf notes.txt $ ls -a . .. .bash_history .bash_logout .bashrc .profile Descargas Documentos Escritorio IC2 lecture.pdf notes.txt $ ls -l total 20 drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Descargas drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Documentos drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Escritorio drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 IC2 -rw-r--r-- 1 sergio sergio 2400000 Oct 25 23:59 lecture.pdf -rw-r--r-- 1 sergio sergio 16 Oct 25 23:59 notes.txt $ ls -la total 52 drwxr-x--- 6 sergio sergio 4096 Oct 25 23:59 . drwxr-xr-x 7 root root 4096 Oct 25 23:58 .. -rw------- 1 sergio sergio 12236 Oct 25 23:59 .bash_history -rw-r--r-- 1 sergio sergio 220 Mar 31 2024 .bash_logout -rw-r--r-- 1 sergio sergio 3771 Mar 31 2024 .bashrc -rw-r--r-- 1 sergio sergio 807 Mar 31 2024 .profile drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Descargas drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Documentos drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 Escritorio drwxr-xr-x 2 sergio sergio 4096 Oct 25 23:59 IC2 -rw-r--r-- 1 sergio sergio 2400000 Oct 25 23:59 lecture.pdf -rw-r--r-- 1 sergio sergio 16 Oct 25 23:59 notes.txt $ ls -lh lecture.pdf -rw-r--r-- 1 sergio sergio 2.3M Oct 25 23:59 lecture.pdf
Let’s go piece by piece:
- Plain
lslists the names, without hidden files. Folders starting with a capital letter come before lowercase files becauselssorts by each letter’s code (capitals go first). ls -aadds whatever starts with a dot:.(the current folder),..(the one above) and your user’s settings files (.bashrc,.profile,.bash_history, which stores the commands you’ve typed). “Hidden” files have nothing secret about them: they just start with a dot so they don’t get in the way.ls -lgives one line per item with all its information.total 20is the disk space used, in 1 KB blocks.ls -lacombines both options: it’s the one people use most in class.ls -lhswaps bytes for human units:2400000bytes become2.3M. Why 2.3 and not 2.4? Becauselscounts in powers of 1024: 2,400,000 / 1024 / 1024 = 2.29, which rounds up to 2.3.
How to read ls -l, column by column
The output of ls -l is scary the first time, but it’s always the same fields in the same order. Look at the lecture.pdf line in the diagram:
| Field | In the lecture.pdf line | What it tells you |
|---|---|---|
| Type | - | Regular file (d directory, l link) |
| Permissions | rw-r--r-- | Who can read, write and execute: you’ll see it in the next topic |
| Links | 1 | How many names point to this file (for a folder, it counts its subfolders) |
| Owner and group | sergio sergio | Whose it is |
| Size | 2400000 | Bytes. For a folder, 4096 is the size of its “index card”, not of what’s inside |
| Date | Oct 25 23:59 | Last modification (if it’s from another year, you see the year instead of the time) |
| Name | lecture.pdf | Always at the end |
You don’t need to open something to know whether it’s a folder or a file: look at the first letter in ls -l. A d means a directory.
cd: moving between folders
cd (change directory) changes the working directory. It prints nothing if all goes well: that’s why I put a pwd between commands, to see where I land each time.
pwd # a path starting with / is looked up from the system root cd /etc pwd # .. is always the folder above (the "parent") cd .. pwd # cd - goes back to the previous folder and prints it cd - # ~ is your home folder, wherever you are cd ~ pwd cd IC2/Practices/P1 pwd # they can be chained: ../.. goes up two levels cd ../.. pwd
The output:
$ pwd /home/sergio $ cd /etc $ pwd /etc $ cd .. $ pwd / $ cd - /etc $ cd ~ $ pwd /home/sergio $ cd IC2/Practices/P1 $ pwd /home/sergio/IC2/Practices/P1 $ cd ../.. $ pwd /home/sergio/IC2
The five shortcuts you should know by heart:
| You type | You go to | In the session |
|---|---|---|
cd or cd ~ | Your home folder | /home/sergio |
cd .. | The folder above | from /etc to / |
cd - | The folder you were in before (and it prints it) | back to /etc |
cd / | The system root | / |
cd ../.. | Two levels up | from P1 to IC2 |
Check the last one by hand: from /home/sergio/IC2/Practices/P1, the first .. leaves you in Practices and the second in IC2. Two jumps, two levels.
Absolute and relative paths (the most common confusion)
A path is the address of a file or folder in the tree. There are two ways to write it, and mixing them up is IC2’s number-one mistake:
- Absolute: starts with
/and describes the whole route from the root. It works wherever you are:/home/sergio/IC2/Practices. - Relative: doesn’t start with
/and is read from the folder you’re in.IC2/Practicesonly works if you’re in/home/sergio.
See it in the tree: in violet, the absolute path; in coral, the relative ../Class_notes, which leaves Practices, goes up to IC2 and comes back down.
Now in the terminal, with the two mistakes you see most in the lab:
# absolute path: starts with / and works from anywhere cd /home/sergio/IC2/Practices pwd # relative path: read from where I am now cd ~ cd IC2/Practices pwd # from Practices, its sibling Class_notes is "up and to the side" cd ../Class_notes pwd cd ~ # with / in front, bash looks for IC2 in the root, not in my folder cd /IC2 # Linux is case-sensitive: ic2 is not IC2 cd ic2 # ./ means "right here": ./IC2 and IC2 are the same relative path cd ./IC2 pwd
Here’s what really comes out:
$ cd /home/sergio/IC2/Practices $ pwd /home/sergio/IC2/Practices $ cd ~ $ cd IC2/Practices $ pwd /home/sergio/IC2/Practices $ cd ../Class_notes $ pwd /home/sergio/IC2/Class_notes $ cd ~ $ cd /IC2 bash: cd: /IC2: No such file or directory $ cd ic2 bash: cd: ic2: No such file or directory $ cd ./IC2 $ pwd /home/sergio/IC2
Why does cd /IC2 fail? Because the leading slash tells bash “start at the root”, and there’s no IC2 folder in the root: yours is at /home/sergio/IC2. And cd ic2 fails because the folder is called IC2, in capitals. On the other hand, cd ./IC2 works: ./ means “right here”, so it’s the same relative path as IC2.
Putting / in front “because it looks clearer”. /Practices isn’t “the Practices folder”, it’s “the Practices folder in the system root“, which doesn’t exist. If you’re not sure, use the full absolute path or check where you are with pwd.
| Situation | Absolute or relative? | Example |
|---|---|---|
| A script or an assignment that must work from anywhere | Absolute | /home/sergio/IC2/Hand_ins |
| Moving around your own lab | Relative | cd ../P2 |
| Going home or to something in it | The ~ shortcut | cd ~/IC2 |
| You don’t know where you are | Absolute (or pwd first) | cd /home/sergio/IC2 |
mkdir and rmdir: creating and removing folders
mkdir (make directory) creates folders and rmdir (remove directory) removes them, but only if they’re empty. That limitation is a safety net, not a flaw.
# mkdir doesn't create missing folders along the way... mkdir Practices/P1 # ...unless you add -p (parents), which creates the whole path mkdir -p Practices/P1 ls -R Practices # creating a folder that already exists is an error mkdir Practices # with -p it doesn't complain: it leaves it as it is mkdir -p Practices # rmdir only deletes EMPTY folders rmdir Practices rmdir Practices/P1 rmdir Practices ls
The real output:
$ mkdir Practices/P1 mkdir: cannot create directory 'Practices/P1': No such file or directory $ mkdir -p Practices/P1 $ ls -R Practices Practices: P1 Practices/P1: $ mkdir Practices mkdir: cannot create directory 'Practices': File exists $ mkdir -p Practices $ rmdir Practices rmdir: failed to remove 'Practices': Directory not empty $ rmdir Practices/P1 $ rmdir Practices $ ls Descargas Documentos Escritorio
What happened, line by line:
mkdir Practices/P1fails becausePracticesdoesn’t exist yet:mkdirdoesn’t create intermediate folders.- With
-p(parents) it does: it createsPracticesandP1inside it.ls -R(recursive) checks it by going into each subfolder. - Creating a folder that already exists is an error (“File exists”)… except with
-p, which doesn’t complain. That’s whymkdir -pis the safe option in scripts. rmdir Practicesfails because it hasP1inside. You have to removeP1first and thenPractices: from the inside out.
mkdir -p IC2/Practices/P1_introduction creates the whole path at once and doesn’t complain if part of it already existed. It’s the fastest way to build a folder structure.
touch and cat: creating files and looking inside
touch creates an empty file (or updates the date of an existing one) and cat (concatenate) shows its content in the terminal.
# touch creates an empty file (0 bytes) if it doesn't exist touch hello.c ls -l hello.c # echo + > writes a line into the file (covered in depth in Redirection) echo '#include <stdio.h>' > hello.c # cat shows the whole content cat hello.c ls -l hello.c # cat with a name that does not exist gives an error cat bye.c
What the terminal shows:
$ touch hello.c $ ls -l hello.c -rw-r--r-- 1 sergio sergio 0 Oct 25 23:59 hello.c $ echo '#include <stdio.h>' > hello.c $ cat hello.c #include <stdio.h> $ ls -l hello.c -rw-r--r-- 1 sergio sergio 19 Oct 25 23:59 hello.c $ cat bye.c cat: bye.c: No such file or directory
Freshly created, hello.c takes up 0 bytes. After writing a line with echo and >, it takes 19: the 18 characters of #include <stdio.h> plus the newline that echo adds at the end. The numbers add up. The > arrow is a redirection: it sends what echo writes to the file instead of the screen. Careful, because > overwrites whatever was inside; you’ll see it calmly in Redirection and pipes.
cat is fine for short files. For a long one (a 300-line .c), use less file: it lets you scroll with the arrows and quit with q.
cp and mv: copying, moving and renaming
cp (copy) and mv (move) are written the same way: command source destination. What changes the result is what the destination is:
- If the destination is an existing folder, the file goes inside with the same name.
- If the destination is a name that doesn’t exist, it’s created with that name (a copy with another name, or a rename).
cd IC2/Practices/P1 # cp source destination: if the destination is a new name, it makes a copy with that name cp exercise1.c exercise1_copy.c ls # if the destination is an existing folder, it copies inside with the same name cp exercise1.c ../P2/ ls ../P2 cd .. # a folder isn't copied without -r (recursive) cp P1 P1_copy cp -r P1 P1_copy ls ls P1_copy cd P1 # mv to a new name in the same folder = rename mv exercise2.c practice_final.c ls # mv to an existing folder = move (the file leaves this place) mv practice_final.c ../../Hand_ins/ ls ls ../../Hand_ins
When you run it:
$ cd IC2/Practices/P1 $ cp exercise1.c exercise1_copy.c $ ls exercise1.c exercise1_copy.c exercise2.c $ cp exercise1.c ../P2/ $ ls ../P2 exercise1.c $ cd .. $ cp P1 P1_copy cp: -r not specified; omitting directory 'P1' $ cp -r P1 P1_copy $ ls P1 P1_copy P2 $ ls P1_copy exercise1.c exercise1_copy.c exercise2.c $ cd P1 $ mv exercise2.c practice_final.c $ ls exercise1.c exercise1_copy.c practice_final.c $ mv practice_final.c ../../Hand_ins/ $ ls exercise1.c exercise1_copy.c $ ls ../../Hand_ins practice_final.c
Look at the warning from cp P1 P1_copy: cp doesn’t copy folders without -r (recursive), and it doesn’t give a red error: it skips the folder with a message and copies nothing. With cp -r, P1_copy does appear with the three files inside. mv, on the other hand, moves folders without any special option.
The diagram sums up the difference between the three commands that touch files:
| I want… | Command | Does the original stay? |
|---|---|---|
| A copy in another folder | cp file folder/ | Yes |
| A copy with another name | cp file new_name | Yes |
| To copy a whole folder | cp -r folder copy | Yes |
| To change the name | mv old new | No (it’s the same file with another name) |
| To take it to another folder | mv file folder/ | No |
mv and cp overwrite without asking if there’s already a file with that name at the destination. If you don’t want surprises, add -i (interactive): cp -i and mv -i ask before overwriting.
rm: deleting without a recycle bin
rm (remove) deletes files. It’s the most dangerous command in the article for one reason: the terminal has no recycle bin. What rm deletes can’t be recovered with a click.
cd IC2 ls # rm deletes the file without asking and without a recycle bin rm test.txt ls # a folder can't be deleted with plain rm rm draft # -i asks before each deletion: I answer n (no) and then y (yes) rm -i notes.txt rm -i very_old.c ls # -r deletes the folder and EVERYTHING inside it rm -r draft ls # what no longer exists can't be deleted twice rm test.txt
Result:
$ cd IC2 $ ls draft notes.txt test.txt very_old.c $ rm test.txt $ ls draft notes.txt very_old.c $ rm draft rm: cannot remove 'draft': Is a directory $ rm -i notes.txt rm: remove regular empty file 'notes.txt'? n $ rm -i very_old.c rm: remove regular empty file 'very_old.c'? y $ ls draft notes.txt $ rm -r draft $ ls notes.txt $ rm test.txt rm: cannot remove 'test.txt': No such file or directory
The important bits of the session:
rm test.txtdeletes without saying anything. Silence, in Linux, means “done”.rm draftfails: a folder needs-r. Another safety net.rm -iasks file by file. I answerednfornotes.txtand it’s still there; I answeredyforvery_old.cand it vanished.rm -r draftdeletes the folder and everything that was inside, without asking.- Deleting something that no longer exists gives an error:
test.txtwent away in the second command.
rm -r in the wrong folder. Before any rm -r, type pwd and ls and read what you’re about to delete. While you’re getting used to it, always use rm -i (or rm -ri with folders) and keep your labs in the shared folder with Windows, which works as a backup.
rmdir and rm -r are not the same. rmdir only removes empty folders (if you get it wrong, nothing happens); rm -r takes everything inside with it. When a folder should be empty, use rmdir: if it isn’t, it warns you.
–help and man: the help is in the terminal itself
You don’t need to memorise every option. Almost every command has a short help with --help:
$ rmdir --help
Usage: rmdir [OPTION]... DIRECTORY...
Remove the DIRECTORY(ies), if they are empty.
--ignore-fail-on-non-empty
ignore each failure to remove a non-empty directory
-p, --parents remove DIRECTORY and its ancestors;
e.g., 'rmdir -p a/b' is similar to 'rmdir a/b a'
-v, --verbose output a diagnostic for every directory processed
--help display this help and exit
--version output version information and exit
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/rmdir>
or available locally via: info '(coreutils) rmdir invocation'
In two seconds you see that rmdir -p a/b removes b and then a, and that -v tells you what it did. For the full explanation there’s the manual: man rmdir. Inside man you scroll with the arrows or the space bar, search with / followed by a word and quit with q.
Keyboard shortcuts that save you time
| Shortcut | What it does |
|---|---|
Tab | Completes the name of a command, file or folder. Pressed twice, it shows the options |
↑ and ↓ | Walk through the commands you’ve already typed |
Ctrl + C | Cancels the running command |
Ctrl + L | Clears the screen (like clear) |
Ctrl + A / Ctrl + E | Jump to the start / end of the line |
!! | Repeats the last command |
Use Tab all the time. Besides saving letters, it warns you about mistakes: if Tab doesn’t complete cd Prac, there’s nothing starting with Prac in that folder.
The folder structure I recommend for IC2
With mkdir -p you build in a moment the structure you’ll use for the whole term. Do it in your shared folder so you can also see it from Windows:
cd ~ # the structure I recommend for IC2: one command per folder, with -p mkdir -p IC2/Practices/P1_introduction mkdir -p IC2/Practices/P2_commands mkdir -p IC2/Class_notes mkdir -p IC2/Hand_ins # ls -R (recursive) walks through every subfolder ls -R IC2
Here’s what really comes out:
$ cd ~ $ mkdir -p IC2/Practices/P1_introduction $ mkdir -p IC2/Practices/P2_commands $ mkdir -p IC2/Class_notes $ mkdir -p IC2/Hand_ins $ ls -R IC2 IC2: Class_notes Hand_ins Practices IC2/Class_notes: IC2/Hand_ins: IC2/Practices: P1_introduction P2_commands IC2/Practices/P1_introduction: IC2/Practices/P2_commands:
ls -R shows each folder with its contents below it: IC2 has Class_notes, Hand_ins and Practices, and Practices has the first two labs, still empty. In this topic’s practice you’ll fill them with files.
Common mistakes
“No such file or directory” almost never means something was deleted. It means the path doesn’t exist from where you are. Check pwd, check ls and review capitals and slashes.
cp folder destination without -r. cp skips the folder with a warning (“omitting directory”) and copies nothing. Folders are copied with cp -r.
rmdir on a folder with things inside gives “Directory not empty”. Don’t fix it with a blind rm -r: first look at what’s there with ls.
Trusting mv and cp to warn you. If the destination exists, they overwrite it silently. Use -i when you’re not sure.
Try it in your terminal
In the programming topics, this is where Python Tutor would go. In Linux, the best tool is the terminal itself: copy this session, which takes a round trip through three folders and leaves everything as it was.
mkdir -p trip/out/back cd trip/out/back pwd cd ../.. pwd ls -R cd ~ rm -r trip ls
What you should see:
$ mkdir -p trip/out/back $ cd trip/out/back $ pwd /home/sergio/trip/out/back $ cd ../.. $ pwd /home/sergio/trip $ ls -R .: out ./out: back ./out/back: $ cd ~ $ rm -r trip $ ls Descargas Documentos Escritorio
What to watch:
mkdir -pcreates the three nested folders with a single command.- After
cd trip/out/back,pwdshows the full absolute path, even though you typed a relative one. cd ../..goes up exactly two levels: frombacktotrip.ls -Rdraws the tree from where you are (.), folder by folder.rm -r triptakes everything away and the lastlsproves your home folder is back to how it started.
Summary
| Command | What for | The option you’ll use most |
|---|---|---|
pwd | Knowing where you are | — |
ls | Seeing what’s there | -la, -lh, -R |
cd | Moving around | .., ~, - |
mkdir / rmdir | Creating / removing empty folders | mkdir -p |
touch / cat | Creating an empty file / viewing content | — |
cp | Copying | -r for folders, -i to avoid overwriting |
mv | Moving or renaming | -i |
rm | Deleting with no recycle bin | -i, -r with care |
--help / man | Help | q to quit man |
Three ideas to take away:
- Before blaming Linux, check where you are:
pwdandlssolve almost every “No such file or directory”. - A path starting with
/starts at the root; one that doesn’t starts in your current folder. cpduplicates,mvchanges place or name andrmdestroys for good: withrm, firstls, then-i.
You know the commands; now it’s time to really use them. In the basic Linux commands practice you’ll explore the system, build your IC2 folder and solve a paths challenge. And once you’ve mastered it, the next topic is Linux permissions, where you’ll finally understand that rw-r--r-- in ls -l.
Did this article help you? Here is how you can support SergioLearns →




What is an operating system — theory with your laptop on a study afternoon, a write() call and a CPU that never rests (and the three programs that weren’t running at the same time)