You have your snapshot taken and a session open on srv-tramontana. In front of you there is a blinking prompt and little else. That screen, which at first sight looks like a limitation, is in fact the most powerful interface the system has: everything that can be done on a Linux server can be done from there, and almost nothing done there is unrepeatable.
This lesson is not a list of commands. It is the lesson where you learn how the interpreter between your fingers and the kernel works: how it reads what you type, how it decides which program to run, how you can type three times faster by using the keyboard properly, and how to chain commands so that one depends on the result of the previous one. From here on, every new command you learn will rest on this mechanism.
By the end you should be able to sit down at any Linux terminal and move without friction: without deleting a whole line by holding down backspace, without retyping a command you already ran ten minutes ago, and without a space in a file name ruining your instruction.
Contents
- Why the command line is still the professional tool
- The REPL cycle: what the shell does with what you type
- Anatomy of a command: command, options and arguments
- Internal and external commands: builtins,
type,whichandcommand -v - How the shell finds an executable
- Tab completion
- The command history
- Editing the command line without suffering
- Chaining commands:
;,&&,||and grouping - Running in the background with
& - Quoting and escaping: when the name has spaces
- Cancelling and exiting
- Why the command line is still the professional tool
The question is a fair one: in 2026, with mature graphical interfaces and web administration panels, why does a professional work in a terminal?
The answer is not nostalgia. It is four properties the graphical interface cannot offer:
- Reproducibility. A command is text. It can be copied, pasted, saved in a document, checked in a code review and run identically six months later. "Click on Settings, then on the Advanced tab, then tick the third box" is not reproducible: it depends on the version, on the language and on the box still being there.
- Automation. What you type by hand today is literally the first line of the script that will do it on its own tomorrow. Between running a command and automating it there is no translation step: it is the same text. In a graphical interface, automating means rewriting the whole process in another language.
- Remote work.
srv-tramontanahas no monitor and never will. When the server is in a data centre or in a cloud, your only door will be SSH. The CLI is designed for that; remote desktop is a patch. - Cost in resources and bandwidth. An SSH session consumes a few kilobytes per minute and works over a poor mobile connection from a train. A remote desktop needs megabits and drops out. When you have an incident at three in the morning from your phone, this will stop being a technical detail.
Now the honest part, because the CLI does not win at everything:
| Criterion | Graphical interface (GUI) | Command line (CLI) |
|---|---|---|
| Learning curve | Gentle: the options are visible | Steep: you have to know they exist |
| Discoverability | High: you explore menus | Low: you need documentation (lesson 02-02) |
| Speed for the expert | Limited by the mouse | Very high |
| Reproducibility | Low | Total |
| Automation | Difficult or impossible | Native |
| Remote work | Heavy, fragile | Light, robust |
| Visual tasks (images, design, diagrams) | Irreplaceable | Unsuitable |
| Resource consumption | High | Minimal |
| Margin for destructive error | Low: it confirms and warns | High: it runs and says nothing |
That last point deserves a pause. The Unix philosophy you saw in Module 1 includes an implicit rule: silence is a sign of success. If a command works, it usually says nothing. And if you ask it to delete a directory tree, it deletes it without asking. The power and the danger are the same property seen from two sides.
The professional conclusion is not "the CLI is better", but: for administering systems, the CLI is the right tool, and not mastering it limits you to doing by hand what others automate.
- The REPL cycle: what the shell does with what you type
Bash does not run what you type. It runs the result of processing what you type. Understanding that difference will save you a lot of surprises.
The shell works in a loop called the REPL (Read–Eval–Print–Loop): it reads, evaluates, prints and starts again.
flowchart TD
A[Show the prompt] --> B[READ: wait for a complete line]
B --> C[SPLIT: break into words by spaces]
C --> D[EXPAND: wildcards, variables, substitutions, ~]
D --> E[RESOLVE: is it a builtin, an alias or an external program?]
E --> F[EXECUTE: launch the process and wait]
F --> G[PRINT: standard output and errors on screen]
G --> H[STORE: exit code in $? and history]
H --> A
Notice the EXPAND step: it happens before anything is run. When you type a command with a *, the program never sees the asterisk; it sees the list of names the shell has put in its place. Wildcards and variables are covered in Module 3, but it is worth knowing now that this intermediate phase exists, because it explains behaviours that otherwise look like magic.
And notice SPLIT: the shell divides the line by spaces before knowing what they mean. That detail is the cause of the quoting problem you will see in section 11.
- Anatomy of a command: command, options and arguments
You already saw the general shape in Module 1. Now we take it apart completely:
- Command: what you want to do. Always the first word.
- Options (or flags, switches): how you want to do it. They start with
-or--. - Arguments (or operands): what you want to do it to. Usually files or paths.
operator@srv-tramontana:~$ ls -l -h /var/log/tramontana
total 32K
-rw-r----- 1 root adm 18K Aug 18 09:14 access.log
-rw-r----- 1 root adm 6.2K Aug 18 09:02 errors.logHere ls is the command, -l and -h are options and /var/log/tramontana is the argument. Without an argument, ls uses a default value (the current directory); without options, it uses its default behaviour.
Short, long and value-taking options
| Form | Example | Notes |
|---|---|---|
| Short | -l |
One letter, one hyphen. Case matters: -r and -R are usually different things |
| Short, grouped | -lh = -l -h |
Only those that take no value can be grouped |
| Long | --human-readable |
Two hyphens, a whole word. More readable in scripts |
| Short with a value | -n 5 or -n5 |
The space is usually optional, but not always |
| Long with a value | --lines=5 or --lines 5 |
With = it is the safest form |
The following three invocations are equivalent:
Professional criterion: use short options when typing by hand (speed) and long ones when writing a script or documenting a procedure (readability). Six months from now, --human-readable explains itself; -h forces you to look at the manual. And beware: -h does not mean the same thing in every command.
The -- separator
A bare -- means "no more options; everything that follows is an argument, even if it starts with a hyphen".
operator@srv-tramontana:~$ touch -- -report.txt
operator@srv-tramontana:~$ ls
-report.txt
operator@srv-tramontana:~$ rm -report.txt
rm: invalid option -- 'e'
Try 'rm ./-report.txt' to remove the file '-report.txt'.
operator@srv-tramontana:~$ rm -- -report.txtWithout --, rm interprets -report.txt as a pile of separate options. It is a rare case when typing by hand, but it stops being rare when a script receives file names from outside: any name starting with a hyphen can alter the command's behaviour. That is why serious scripts (Module 4) use -- before the data.
- Internal and external commands: builtins,
type, which and command -v
type, which and command -vNot every command is a program. There are two categories:
- Builtins (internal): Bash implements them. There is no file to run; the shell does the work itself. They are extremely fast.
- External: they are executables on disk (
/bin/ls,/usr/bin/find...). The shell creates a new process to run them.
The tool for telling them apart is type:
operator@srv-tramontana:~$ type cd
cd is a shell builtin
operator@srv-tramontana:~$ type ls
ls is aliased to `ls --color=auto'
operator@srv-tramontana:~$ type -a ls
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
operator@srv-tramontana:~$ type grep
grep is /usr/bin/greptype -a shows all the possible resolutions, in order of priority. It is the diagnostic tool for when a command "does not do what it should": there is nearly always an alias or a script sitting in front of the real program.
| Tool | What it does | When to use it |
|---|---|---|
type <cmd> |
Says what it is: builtin, alias, function or file | Diagnosis. The most complete |
type -a <cmd> |
All resolutions, by priority | When you suspect an alias or a duplicate |
which <cmd> |
Path of the external executable | Quick, but it ignores builtins and aliases |
command -v <cmd> |
Resolution in one line | In scripts: it is POSIX and portable |
which cd returns nothing and fails, because cd is not a file. That is exactly the limitation that makes which useless as a general diagnostic tool.
Why cd has to be a builtin
This question comes up in technical interviews, and its answer explains something real about how the system works.
Every process on Linux has its own working directory, which is a private attribute of the process. When you run an external program, the shell creates a child process and that child inherits a copy of the parent's environment. The child can change whatever it likes in its copy: when it finishes, its copy disappears and the parent carries on exactly as before.
flowchart LR
A[Bash<br/>cwd = /home/operator] -->|creates child| B[Child process<br/>cwd = /home/operator]
B -->|changes its cwd| C[Child process<br/>cwd = /etc]
C -->|finishes| D[Bash<br/>cwd = /home/operator<br/>UNCHANGED]
If cd were an external program, it would change the directory of its own process and die immediately. Your shell would never move. That is why cd has to run inside the shell's own process, that is, be a builtin.
The same logic applies to export, alias, source, exit, umask and history: anything that modifies the state of the shell must be internal. Keep hold of this idea, because it is what explains why a script cannot change the directory of whoever calls it (Module 4).
- How the shell finds an executable
When you type grep, the shell does not comb the disk. It follows a strict order:
- Is it an alias? It substitutes it.
- Is it a shell function? It runs it.
- Is it a builtin? It runs it.
- If not, it looks for an executable file with that name in the directories listed in the
PATHvariable, in order, and uses the first one it finds. - If it does not find it:
command not found.
These are directories separated by :. It is a list of places to look, not a search across the whole disk. Two practical consequences:
- A program sitting in a directory outside the
PATHwill not run just by typing its name. You have to give its path: that is why your scripts in/home/operator/scriptswill be launched as./report.shor with the full path. - The order matters. If there were two executables with the same name in two
PATHdirectories, the one appearing first wins.
The current directory is not in the PATH, and that is a deliberate security decision: if it were, leaving a file called ls in a shared directory would be enough to trick anyone who walked in. Never add . to the PATH.
The full detail of PATH (how it is modified, where it is defined and what exactly an environment variable is) is the subject of lesson 03-01. Here the concept is enough.
- Tab completion
The Tab key is the one that will improve your speed the most, and not only by saving keystrokes: completing with Tab prevents typos. If the name completes by itself, it exists.
How it works:
- One press with a single match: it completes the rest.
- One press with several matches: it completes the common part and stops there (usually with a beep).
- Two presses: it shows the list of all the matches.
operator@srv-tramontana:~$ cd /var/log/tram<Tab>
operator@srv-tramontana:~$ cd /var/log/tramontana/
operator@srv-tramontana:~$ ls /var/log/tramontana/<Tab><Tab>
access.log errors.log
operator@srv-tramontana:~$ ls /var/log/tramontana/a<Tab>
operator@srv-tramontana:~$ ls /var/log/tramontana/access.logWhat it completes according to the position in the line:
| Position | What it offers |
|---|---|
| First word | Commands, builtins, aliases and functions |
| After a command | Files and directories |
After ~ |
User names: ~ope<Tab> → ~operator/ |
After $ |
Variable names |
After - or -- |
The command's options (if completion is installed) |
That last row depends on the bash-completion package, present by default in Ubuntu Server 24.04. Thanks to it, many commands complete their own options and even their arguments:
A hygiene tip: if you type a whole long name without Tab and it then fails, you have wasted your time twice. Type three letters and press Tab. If it does not complete, the file is not where you think it is, and you have just found the mistake before running anything.
- The command history
Bash keeps what you run in memory during the session and dumps it to the ~/.bash_history file on exit. That means you never have to retype the same thing twice.
operator@srv-tramontana:~$ history
...
147 df -h
148 ls -l /var/log/tramontana
149 uptime
150 history
operator@srv-tramontana:~$ history 3
149 uptime
150 history
151 history 3Ways of reusing the history:
| Shortcut | What it does |
|---|---|
| Up / down arrow | Walks through the history backwards and forwards |
| Ctrl+R | Incremental reverse search: type a fragment and the command appears |
| Ctrl+R again | Jumps to the previous match |
| Ctrl+G or Ctrl+C | Cancels the search and leaves the line as it was |
!! |
The whole of the last command |
!148 |
Command number 148 in the history |
!ls |
The last command that started with ls |
!$ |
The last argument of the previous command |
!* |
All the arguments of the previous command |
Ctrl+R is, by some distance, the most profitable shortcut in this section. Press Ctrl+R, type tram and Bash shows you the most recent command containing that string. Press Enter to run it or the right arrow to edit it first.
The two most useful idioms in day-to-day work are !! and !$:
operator@srv-tramontana:~$ cat /etc/tramontana/app.conf
cat: /etc/tramontana/app.conf: Permission denied
operator@srv-tramontana:~$ sudo !!
sudo cat /etc/tramontana/app.conf
[sudo] password for operator:
# Tramontana Bookings configuration
db_host=127.0.0.1
...sudo !! reruns the previous command with privileges. Bash shows the expanded line before running it, which gives you the chance to see what is about to happen.
operator@srv-tramontana:~$ ls -l /var/log/tramontana/access.log
-rw-r----- 1 root adm 18432 Aug 18 09:14 /var/log/tramontana/access.log
operator@srv-tramontana:~$ sudo tail -n 3 !$
sudo tail -n 3 /var/log/tramontana/access.log
2026-08-18 09:14:02 GET /bookings 200 user=mvidal
2026-08-18 09:14:07 POST /bookings 201 house=mas-figueres
2026-08-18 09:14:11 GET /houses 200 user=anon!$ recovers the last argument: the classic "look first, act second" pattern without retyping the path.
A security warning worth taking on board right now: the history is a plain text file. If you type a password as an argument to a command, it is saved in ~/.bash_history. Never pass secrets on the command line; the correct handling of credentials is covered in lesson 06-05.
- Editing the command line without suffering
Bash uses the readline library, which brings the editing shortcuts of the Emacs editor. The same shortcuts work in many other terminal programs, so learning them pays off beyond the shell.
| Shortcut | Action |
|---|---|
| Ctrl+A | Go to the beginning of the line |
| Ctrl+E | Go to the end of the line |
| Alt+B | Move back one word |
| Alt+F | Move forward one word |
| Ctrl+W | Delete the word before the cursor |
| Ctrl+U | Delete from the cursor back to the beginning |
| Ctrl+K | Delete from the cursor to the end |
| Ctrl+Y | Paste back the last thing you deleted with W, U or K |
| Alt+D | Delete the next word |
| Ctrl+T | Swap the two characters around the cursor |
| Ctrl+_ | Undo the last edit |
| Ctrl+L | Clear the screen (keeping the line) |
A mnemonic: A for the start of the alphabet, E for end, K for kill to the end, U for undo back to the beginning, W for word.
The most frequent practical case: you type a long command, spot a typo at the beginning and you are at the end. Instead of holding down backspace, Ctrl+A, fix it, Ctrl+E, Enter. And if the whole line is wrong: Ctrl+U wipes it in one go.
A useful detail: in many terminal emulators Alt works directly; if it does not, the alternative is to press Esc and release it before the letter (Esc then B is equivalent to Alt+B).
- Chaining commands:
;, &&, || and grouping
;, &&, || and groupingYou can put several commands on a single line, and the difference between the separators is not cosmetic: it is control logic.
To understand it you need the exit code: every command, when it finishes, returns a number. 0 means success; any other value means failure. You check it with $? (we will develop this in lesson 02-02).
| Operator | Name | Behaviour |
|---|---|---|
; |
Sequence | Runs the next one always, whatever happens |
&& |
Logical AND | Runs the next one only if the previous one succeeded (code 0) |
|| |
Logical OR | Runs the next one only if the previous one failed (code ≠ 0) |
operator@srv-tramontana:~$ cd /directory/that/does/not/exist ; echo "still here"
-bash: cd: /directory/that/does/not/exist: No such file or directory
still here
operator@srv-tramontana:~$ cd /directory/that/does/not/exist && echo "still here"
-bash: cd: /directory/that/does/not/exist: No such file or directory
operator@srv-tramontana:~$ cd /directory/that/does/not/exist || echo "could not get in"
-bash: cd: /directory/that/does/not/exist: No such file or directory
could not get inThe difference is critical in practice. Compare these two lines:
If the directory does not exist, the first one changes its mind but not its intention: it does not get in, and it deletes old in whatever directory you happened to be in, which may be your home directory. The second does nothing. A rule to adopt from today: when a command depends on the previous one having worked, use &&, never ;.
The three can be combined, and you can also group with parentheses:
operator@srv-tramontana:~$ ls /opt/tramontana/app && echo "OK: the app is there" || echo "WARNING: the app is missing"
executable templates version.txt
OK: the app is thereParentheses group commands in a subshell: a child process with its own working directory and its own state.
operator@srv-tramontana:~$ pwd
/home/operator
operator@srv-tramontana:~$ (cd /var/log/tramontana && ls)
access.log errors.log
operator@srv-tramontana:~$ pwd
/home/operatorThe cd inside the parentheses affected only the subshell; when it comes back, you are still where you were. It is exactly the mechanism from section 4, now used in your favour: go in, do something, and do not let the cd contaminate your session.
With braces { ...; } you group without creating a subshell (the changes do affect your session). It is a distinction we will pick up again when writing scripts in Module 4.
- Running in the background with
&
&An & at the end of a command launches it in the background: the shell does not wait for it to finish and gives you the prompt back immediately.
operator@srv-tramontana:~$ sleep 60 &
[1] 4127
operator@srv-tramontana:~$ jobs
[1]+ Running sleep 60 &
operator@srv-tramontana:~$ fg %1
sleep 60[1]is the job number within this session;4127is the process's PID in the system.jobslists the session's jobs,fgbrings one to the foreground andbgresumes a stopped one in the background.Ctrl+Zstops (does not kill) the foreground process and gives you the prompt back.
These are only the notions you need to recognise the syntax. Full job control, processes, signals and what happens to a background process when you close the session are the subject of lesson 03-06.
- Quoting and escaping: when the name has spaces
Go back to the REPL cycle in section 2: the shell splits the line by spaces before running anything. That is the explanation for a classic mistake:
operator@srv-tramontana:~$ ls
august report.txt bookings.csv
operator@srv-tramontana:~$ rm august report.txt
rm: cannot remove 'august': No such file or directory
rm: cannot remove 'report.txt': No such file or directoryrm never saw a name with a space: it received two arguments, august and report.txt. The shell did its job; the problem is that you did not tell it the space was part of the name.
Three ways to fix it:
rm 'august report.txt' # single quotes
rm "august report.txt" # double quotes
rm august\ report.txt # backslash escaping the spaceAnd the fourth, the one you will actually use: type aug and press Tab. Bash completes the name and escapes the space for you.
The difference between the three mechanisms:
| Mechanism | What it protects | What is still interpreted |
|---|---|---|
'single quotes' |
Everything, literally | Nothing. You cannot even put a single quote inside |
"double quotes" |
Spaces and wildcards | $variable, `command`, $(command) and \ |
\ (backslash) |
The next character | The rest of the line |
operator@srv-tramontana:~$ echo 'The user is $USER'
The user is $USER
operator@srv-tramontana:~$ echo "The user is $USER"
The user is operatorThe practical rule until Module 3 is simple: if you want the text exactly as it is, single quotes; if you expect something inside to be substituted, double quotes. Why it is substituted and what else can be substituted is the content of lesson 03-01.
A point of style that applies to srv-tramontana: do not put spaces in file names on a server. Use hyphens or underscores (august-report.txt). This is not fussiness: every space is a trap waiting for someone to write a script without quotes.
- Cancelling and exiting
Three keystrokes that need telling apart properly, because they are often confused:
| Combination | What it does | When to use it |
|---|---|---|
| Ctrl+C | Sends the interrupt signal to the foreground program | A command has hung or is taking too long |
| Ctrl+D | Sends end of input (EOF) | Finishing typing data; on an empty line, it closes the session |
exit |
Ends the shell explicitly | Closing the session cleanly, above all over SSH |
| Ctrl+Z | Stops (does not kill) the process and leaves it in the background | Parking something for a moment; you pick it up again with fg |
The difference between Ctrl+C and Ctrl+D matters: Ctrl+C interrupts, Ctrl+D says there is no more data. If a command seems to be hanging without doing anything, very often it is waiting for you to type something at the keyboard and the right way out is Ctrl+D, not Ctrl+C.
And Ctrl+Z kills nothing, it only suspends. It is a frequent mistake to believe you have closed an editor with Ctrl+Z when in fact you have left it stopped in the background, holding the file locked.
Common Mistakes and Tips
Using ; where && was called for. It is the mistake in this chapter with the most serious consequences, because it only shows up when something fails, that is, at the worst possible moment. Chain with && by default.
Typing long paths by hand. Every character typed is an opportunity for a typo. Always Tab.
Trusting which to diagnose. It does not see builtins or aliases. If something behaves oddly, type -a is the answer.
Forgetting that Linux is case-sensitive. Bookings.csv and bookings.csv are two different files. Coming from Windows, this bites during the first few weeks.
Unprotected spaces. If a name has spaces and you do not quote it, the shell will see several arguments. And if the command was rm, it will delete things you did not want deleted.
Copying commands from the internet without reading them. Especially those starting with sudo or containing rm -rf. Before running something you do not understand, read it in full and, if need be, look it up in the manual (lesson 02-02).
Tip: run the harmless command first. Are you about to delete using a pattern? Run ls with the same pattern first and see what comes out. Then press the up arrow, change ls for rm and run it. It is the habit that separates those who have lost data from those who have not.
Tip: split a long line over several. A backslash at the end of the line lets you continue on the next one, and it makes complex commands far more readable when you paste them into documentation.
Tip: Ctrl+L instead of clear. It is faster and you do not lose the line you were typing.
Exercises
Exercise 1: reconnaissance of the shell
On srv-tramontana, answer with commands (not from memory):
- Is
echoa builtin, an external program, or both? - How many directories are there in your
PATH? - Does
lshave an alias defined? Which one? - Why does
which cdreturn nothing?
Exercise 2: Luis's trap
Luis Ferrer sends you this line over chat to clean up the application's temporary dumps, saying he "tested it on his laptop and it works fine":
Explain what can go wrong, rewrite it safely and add a prior check that shows you what is going to be deleted before deleting it.
Exercise 3: keyboard speed
Without using the mouse and without deleting character by character:
- Type
ls -l /var/log/tramontana/access.logand run it. - Now run
wc -lon that same file without retyping the path. - Recover the first command from the history and modify it to show
errors.loginstead ofaccess.log, using only editing shortcuts. - Create a file called
marta report.txt, check that it exists and delete it. Explain why the name is a bad idea on a server.
Solutions
Solution 1
Both. Bash has its own echo builtin and /usr/bin/echo also exists. The builtin wins, because internal commands take priority over the PATH. It is a frequent case: echo, test, kill and printf exist in both forms, and their options do not always match between them, which explains some baffling behaviour in scripts ported from one system to another.
Six directories, separated by :. You can count them by eye; in Module 3 you will see how to do it with a command.
Yes: Ubuntu defines ls --color=auto in ~/.bashrc. That is why your directories come out in blue: it is not ls doing it on its own, it is the alias. Aliases are covered in 03-01.
which cd returns nothing because cd is not a file on disk: it is a builtin. And it has to be one, because it must change the working directory of the shell's own process, something a child process cannot do to its parent.
Solution 2
What can go wrong. The semicolon runs rm -r * whatever happens with the cd. If /srv/tramontana/backups/temp does not exist, is misspelled, or the directory has been renamed, cd fails and rm -r * runs in the current directory. If at that moment you were in /home/operator, you have just deleted your home directory, including /home/operator/scripts. If you were in /opt/tramontana, you have taken the application out with it.
The fact that it "works on Luis's laptop" is precisely the warning sign: it works as long as the directory exists. The failure appears the day it does not, which is the day nobody is watching.
Safe version:
# 1. Look first, without touching anything
operator@srv-tramontana:~$ ls -la /srv/tramontana/backups/temp
total 12
drwxr-x--- 2 operator operator 4096 Aug 18 08:30 .
drwxr-x--- 3 operator operator 4096 Aug 18 08:30 ..
-rw-r----- 1 operator operator 842 Aug 17 23:00 dump-2026-08-17.tmp
# 2. Chain with && and use -I, which asks for ONE confirmation if there are many files
operator@srv-tramontana:~$ cd /srv/tramontana/backups/temp && rm -rI ./*Improvements applied:
&&instead of;: if thecdfails, nothing is deleted. This is the important change.ls -lafirst: you see exactly what is there before destroying it../*instead of*: it protects against names starting with a hyphen.-I: it asks for a single confirmation when there are more than three items. Less annoying than-iand enough to make you stop and think.
An even better alternative, which avoids the cd entirely and does not leave your session in another directory:
How you would put it to Luis: not that his command is badly written, but that it is missing the condition. The ; says "do this and then that"; && says "do that only if this went well". In a clean-up with rm -r, that difference is what separates routine maintenance from an incident.
Solution 3
operator@srv-tramontana:~$ ls -l /var/log/tramontana/access.log
-rw-r----- 1 root adm 18432 Aug 18 09:14 /var/log/tramontana/access.log
operator@srv-tramontana:~$ sudo wc -l !$
sudo wc -l /var/log/tramontana/access.log
412 /var/log/tramontana/access.log!$ recovers the last argument of the previous command. Bash shows the line already expanded before running it, which lets you verify that it points where you think it does.
For point 3, the sequence with shortcuts:
- Up arrow twice (or
Ctrl+Rand typeaccess) until you recoverls -l /var/log/tramontana/access.log. Ctrl+Wdeletes the last word, which in this case is the whole path back to the preceding space. Since you only want to change the file name, this is cleaner:Alt+Bto move back word by word until you are onaccess, delete that word withAlt+Dand typeerrors.- Enter.
operator@srv-tramontana:~$ ls -l /var/log/tramontana/errors.log
-rw-r----- 1 root adm 6348 Aug 18 09:02 /var/log/tramontana/errors.logWith long names, Ctrl+A to go to the beginning and Alt+F to move forward word by word is usually quicker than holding down the left arrow.
For point 4:
operator@srv-tramontana:~$ touch 'marta report.txt'
operator@srv-tramontana:~$ ls -l marta*
-rw-rw-r-- 1 operator operator 0 Aug 18 10:22 'marta report.txt'
operator@srv-tramontana:~$ rm 'marta report.txt'Notice that Ubuntu's ls shows the name in quotes precisely to warn you that it contains a space.
Why it is a bad idea on a server: the file works perfectly well as long as you handle it by hand with Tab, but the day it turns up in a script without quotes it will break, and it will do so in the worst possible way: not by failing, but by treating marta and report.txt as two paths. In an rm, that is a wrong deletion; in a copy loop, a file that does not get backed up. The professional convention is marta-report.txt or marta_report.txt.
Conclusion
You are no longer looking at a black screen: you are handling an interpreter whose workings you understand.
- The CLI is the professional tool because it is reproducible, automatable, remote and lightweight, not out of tradition; and its honest downside is that it neither forgives nor warns.
- The shell follows a REPL cycle in which it expands before executing: the program never sees exactly what you typed.
- A command has three parts, its options can be short, grouped, long or value-taking, and
--closes the list of options. - There are builtins and external commands;
type -ais your diagnostic tool, andcdhas to be a builtin because no child can move its parent. - The shell locates executables by walking the
PATHin order, and the current directory is not there for security reasons. - Tab saves you keystrokes and, above all, typos; Ctrl+R,
!!and!$save you retyping; the readline shortcuts save you the endless backspace. ;,&&and||are control logic, not punctuation:&&is your default option when one command depends on the previous one.- Spaces in names are protected with single quotes, double quotes or a backslash, and the best thing is not to have them at all.
With this you can write commands fluently. What is missing is the other pillar of self-sufficiency: knowing what commands exist and what each option does without depending on a search engine. In the next lesson, Getting Help and System Documentation, you will learn to read a man page from start to finish, to understand the notation of the SYNOPSIS, to move around the eight sections of the manual, to find a command when you do not even know its name, and to resolve a real question from Luis Ferrer using nothing but what is already installed on srv-tramontana. It is the lesson that turns "I don't know how to do it" into "I don't know it yet".
Linux Course: From Beginner to System Administrator
Module 1: Introduction to Linux
- What Is Linux?
- History of Linux
- Linux Distributions
- Installing Linux
- First Contact with the System
- The Linux File System Structure
Module 2: Basic Linux Commands
- Introduction to the Command Line
- Getting Help and System Documentation
- Navigating the File System
- File and Directory Operations
- Viewing and Editing Files
- Hard and Symbolic Links
- File Permissions and Ownership
Module 3: Advanced Command-Line Skills
- The Shell Environment: Variables, Aliases and History
- Using Wildcards and Regular Expressions
- Searching Files and Content: find, locate and grep
- Pipes and Redirection
- Text Processing: cut, sort, uniq, sed and awk
- Process Management
- Scheduling Tasks with Cron
- Networking Commands
Module 4: Shell Scripting
- Introduction to Shell Scripting
- Variables and Data Types
- Script Input, Output and Arguments
- Control Structures
- Functions and Libraries
- Debugging and Error Handling
- Production Scripts: Best Practices
Module 5: System Administration
- User and Group Management
- sudo and Special Permissions
- Package Management
- Disk Management
- systemd and Service Management
- System Logs: journald and syslog
- System Monitoring and Performance Tuning
- Backup and Restore
Module 6: Networking and Security
- Network Configuration
- SSH and Remote Access
- Firewalls and Perimeter Security
- Intrusion Detection Systems
- Secrets Management and TLS Certificates
- Securing Linux Systems
Module 7: Advanced Topics
- The Boot Process and System Recovery
- Advanced Diagnostics: strace, perf and eBPF
- Linux Kernel Tuning
- Virtualization with Linux
- Linux Containers and Docker
- Automation with Ansible
- High Availability and Load Balancing
