🐧 Ubuntu Command Line Interface: A Complete Tutorial
Ubuntu is the Linux distribution most web servers run, and its command line is where backend work actually happens. Deploy a Node app, tail a log at 2 a.m., set file permissions, install a package — all of it flows through the terminal. This reference takes you from the very first prompt to writing your own shell script, one clear command at a time.
Reference & Extra Tutorials · Resources · The Server Environment
🎯 What This Covers
By the end of this reference, you will be able to:
- Read the shell prompt and understand the
command [options] [arguments]structure - Navigate the filesystem and manage files with the essential dozen commands
- Read and change file permissions with
chmodand ownership withchown - View and search text with
cat,less,grep, andfind - Chain commands with pipes and redirection to build powerful one-liners
- Install software with
aptand write your first executable Bash script
Estimated Time: 60 minutes
Practice: Scaffold a project, set permissions, and write a small backup script.
In This Tutorial
The Shell & the Prompt
When you open a terminal, you're talking to a program called the shell. On Ubuntu that's usually Bash (the Bourne Again SHell). The shell reads what you type, hands the instruction to the operating system, and prints the result. The window it runs in is the terminal; people use "terminal," "shell," and "command line" almost interchangeably.
Open one with Ctrl + Alt + T, or search "Terminal" in the applications menu. On Windows, install WSL (Windows Subsystem for Linux) to get a genuine Ubuntu shell — nearly every backend tool assumes this environment.
Reading the prompt
username@hostname:~$
| Part | Meaning |
|---|---|
username | The account you're logged in as |
hostname | The name of the machine |
~ | Your current directory (~ is your home folder) |
$ | A regular user (a # means root/administrator) |
When a tutorial shows $ ls, the $ just represents the prompt — you type only ls.
💡 The construction-site analogy
A GUI app is a pre-built house: ready to move into, but you can only change what the builder allowed. The command line is the raw lumber and power tools — steeper to learn, but you can build exactly what you need, and there's no server room on earth without one.
Command Structure
Almost every command follows one shape:
command [options] [arguments]
- command — the program to run (
ls,cp,grep) - options — flags that change behavior, prefixed with
-or-- - arguments — what the command acts on (filenames, paths, text)
For example, in ls -la /home: ls is the command, -la are two options combined (long format plus all files), and /home is the directory argument.
📖 The recipe analogy
A command is a recipe. The command is the dish, the options are the preparation notes ("dice finely," "cook slowly"), and the arguments are the ingredients. Same command, different options and arguments, different result.
✅ Two habits that pay off immediately
- Tab auto-completes file and command names — faster and typo-proof
command --helpandman commandshow usage without leaving the terminal (press q to exitman)
Managing Files & Folders
Create: mkdir and touch
mkdir my-project # one new folder
mkdir docs images styles # several at once
mkdir -p src/components/ui # -p builds the whole nested path
touch notes.txt # create an empty file
touch index.html style.css # create several
The -p ("parents") flag creates every missing folder in a path instead of failing because a middle folder doesn't exist yet.
Copy & move: cp and mv
cp report.txt backup.txt # copy a file (original stays)
cp -r templates/ new-project/ # -r copies a whole folder tree
mv report.txt documents/ # move a file into a folder
mv report.txt final.txt # rename (move to a new name)
mv does double duty: moving and renaming are the same operation — renaming is just "move to the same folder under a new name." The key difference from cp: mv leaves nothing behind, while cp keeps the original.
Delete: rm and rmdir
rm notes.txt # delete a file
rm -r old-project/ # -r deletes a folder and its contents
rm -ri old-project/ # -i asks before each deletion (safer)
rmdir empty-folder/ # only removes an EMPTY folder
⚠️ There is no Trash on the command line
rm deletes permanently and immediately — no Recycle Bin, no undo. Read the filename twice before pressing Enter, be careful with wildcards like rm *.log, and never run rm -rf / or paste a destructive command you don't understand. Add -i while you're learning so it asks before each deletion.
Viewing & Searching Text
cat, less, head, tail
cat notes.txt # print a whole (small) file
less big.log # page through a large file (q to quit)
head -n 20 data.csv # first 20 lines
tail -n 50 app.log # last 50 lines
tail -f /var/log/syslog # follow a log live as it grows
tail -f is the one you'll reach for constantly when debugging a running server — it streams new log lines as they appear.
grep — search inside files
grep "ERROR" app.log # lines containing ERROR
grep -i "error" app.log # case-insensitive
grep -rn "TODO" src/ # recursive, with line numbers
grep -c "404" access.log # count matching lines
find — search for files
find . -name "*.js" # every .js file below here
find . -type d -name "node_modules" # directories with that name
find /home -type f -size +100M # files larger than 100 MB
find . -type f -mtime -7 # modified in the last 7 days
The . means "start in the current directory," -name matches the filename (quote the wildcard so the shell doesn't expand it first), and -type f/-type d restrict to files or directories.
💡 Quote your wildcards in find
Always write find . -name "*.js" with quotes. Without them, the shell expands *.js before find ever runs, and you get confusing results. The quotes hand the pattern to find untouched.
Permissions & Ownership
Every file has permissions for three groups — the owner, the group, and others — across three actions: read, write, and execute. Run ls -l and you'll see them as a string like -rwxr-xr--.
chmod — change permissions
The numeric ("octal") form adds up read (4), write (2), and execute (1) for each group. So 7 is read+write+execute, 5 is read+execute, 4 is read-only.
chmod +x deploy.sh # make a script executable
chmod 755 deploy.sh # rwx for owner, r-x for group and others
chmod 644 config.json # rw- for owner, r-- for everyone else
chmod -R 755 public/ # apply recursively to a folder
| Octal | Symbolic | Typical use |
|---|---|---|
755 | rwxr-xr-x | Scripts and directories |
644 | rw-r--r-- | Regular files |
700 | rwx------ | Private, owner-only |
chown — change ownership
sudo chown username file.txt # change the owner
sudo chown username:group file.txt # change owner and group
sudo chown -R www-data:www-data /var/www # recursive, for web files
⚠️ Don't reach for 777
Setting chmod 777 gives everyone read, write, and execute — a common "just make it work" move that's a genuine security hole. Grant the least permission that does the job: 644 for files, 755 for directories and scripts.
Pipes & Redirection
The real power of the shell is combining small commands. A pipe (|) feeds one command's output into the next; redirection (>, >>) sends output to a file.
Redirection
command > out.txt # write output to a file (overwrite)
command >> out.txt # append to a file
command 2> err.txt # redirect only errors
command > out.txt 2>&1 # both output and errors to one file
Pipes
ls -la | grep ".txt" # list, then keep only .txt lines
cat access.log | wc -l # count lines in a file
du -h | sort -rh | head -10 # ten biggest items, largest first
history | grep git # find past git commands
📖 The assembly-line analogy
Piping is a factory assembly line. Each command is a station that takes raw material (input), does one job, and passes the result to the next station. A chain of simple stations turns raw data into a finished product — exactly how cat log | grep ERROR | sort | uniq -c turns a messy log into a tidy count of each error.
Packages & Services
apt — install software
Ubuntu manages software with apt. Update the package lists first, then install.
sudo apt update # refresh the list of available packages
sudo apt upgrade # upgrade installed packages
sudo apt install nodejs npm # install packages
sudo apt remove package-name # remove a package
apt search keyword # search for a package
sudo ("superuser do") runs a command with administrative rights — required for anything that changes the system, like installing software.
systemctl — manage services
systemctl status nginx # is it running?
sudo systemctl start nginx # start it
sudo systemctl restart nginx # restart it
sudo systemctl enable nginx # start automatically at boot
Watching the system
df -h # disk space, human-readable
du -sh /var/log # total size of a directory
top # live view of processes (q to quit)
ps aux | grep node # find running node processes
💡 update then install
Always run sudo apt update before installing. It refreshes the catalog of available versions; skipping it can install an outdated package or fail to find a new one.
Your First Shell Script
A shell script is just a file of commands the shell runs top to bottom. It's how you turn a repetitive chore into a single command.
#!/bin/bash
# The first line (the "shebang") tells the system to run this with bash.
echo "Hello, world!"
# Variables — no spaces around the =
name="Ray"
echo "Hello, $name!"
# A conditional
if [ "$name" = "Ray" ]; then
echo "Welcome back, Ray."
else
echo "Who goes there?"
fi
# A loop
for i in 1 2 3; do
echo "Count: $i"
done
Make it executable, then run it:
chmod +x hello.sh # give it execute permission
./hello.sh # run it (the ./ means "in this directory")
A useful example: a timestamped backup
#!/bin/bash
# Back up a folder into a timestamped tar.gz archive.
source_dir="$HOME/documents"
backup_dir="$HOME/backups"
timestamp=$(date +%Y%m%d_%H%M%S) # command substitution
mkdir -p "$backup_dir"
tar -czf "$backup_dir/backup_$timestamp.tar.gz" "$source_dir"
echo "Backup created: $backup_dir/backup_$timestamp.tar.gz"
The $(date ...) is command substitution: the shell runs date and drops its output right into the string. Quoting variables like "$source_dir" keeps paths with spaces from breaking.
Output
$ ./backup.sh
Backup created: /home/username/backups/backup_20260731_142530.tar.gz
Command Cheat Sheet
Keep this within reach — these cover the vast majority of daily terminal work.
| Command | What it does | Example |
|---|---|---|
pwd | Print working directory | pwd |
ls | List contents | ls -lh |
cd | Change directory | cd ../src |
mkdir | Make a directory | mkdir -p a/b/c |
touch | Create an empty file | touch app.js |
cp | Copy | cp -r src/ dist/ |
mv | Move or rename | mv a.txt b.txt |
rm | Delete (permanent!) | rm -r build/ |
cat | Print a file | cat notes.txt |
less | Page through a file | less big.log |
grep | Search inside files | grep -rn TODO src/ |
find | Search for files | find . -name "*.js" |
chmod | Change permissions | chmod +x run.sh |
sudo | Run as administrator | sudo apt update |
apt | Manage packages | apt install nodejs |
Practice & Quiz
🏋️ Exercise 1: Scaffold and secure a project
Goal: From your home directory, build this tree, then make the script executable and confirm the layout:
my-app/
├── index.js
├── run.sh
└── src/
└── utils.js
💡 Hint
Use mkdir -p for the nested folder, touch for the files, chmod +x for the script, and ls -R to verify.
✅ Solution
cd ~
mkdir -p my-app/src
cd my-app
touch index.js run.sh src/utils.js
chmod +x run.sh
# Verify
ls -R
# .:
# index.js run.sh src
# ./src:
# utils.js
🏋️ Exercise 2: Count errors in a log
Goal: In a file app.log, count how many lines contain the word ERROR, case-insensitively, using a pipe.
✅ Solution
grep -i "error" app.log | wc -l
# or, equivalently, grep's own counter:
grep -ic "error" app.log
🎯 Quick Quiz
Question 1: Which command permanently deletes a folder and everything inside it?
Question 2: What does the | (pipe) do?
Question 3: What does chmod 755 run.sh grant?
Best Practices & Pitfalls
✅ Do
- Use Tab completion constantly — it's faster and prevents typos
- Run
pwdandlsto orient yourself before any destructive command - Quote paths that contain spaces:
cd "My Folder" - Run
sudo apt updatebefore installing packages - Grant the least permission that works —
644for files,755for scripts - Read
command --helpbefore running anything unfamiliar
❌ Don't
- Run
rm -rfon a path you haven't double-checked — there is no undo - Paste commands from the internet without understanding them
- Reach for
chmod 777orsudoto "just make it work" - Forget that Ubuntu is case-sensitive —
App.js≠app.js - Assume wildcards are harmless — preview
rm *.logwithls *.logfirst
⚠️ The wildcard trap
# Intended: delete temp files
rm temp *.log
# Oops — the stray space means "delete a file named temp
# AND every .log file." The shell expands wildcards BEFORE rm runs.
Before any destructive wildcard, run the same pattern through ls first to see exactly what it will match.
Summary
🎉 Key Takeaways
- The shell reads
command [options] [arguments]— and Tab plus--helpare your best friends pwd,ls, andcdorient and move you through a single case-sensitive tree rooted at/mkdir,touch,cp,mv, andrmcreate and manage files — andrmdeletes permanentlychmodandchowncontrol access; grant the least permission that works- Pipes and redirection chain small commands into powerful one-liners, and a few lines of Bash automate the rest
📚 Additional Resources
- Ubuntu — The Linux command line for beginners
- Ubuntu — Using the terminal
- Microsoft — Install WSL on Windows
🚀 What's Next?
You've reached the end of the Reference & Extras track. Everything backend in this bootcamp — Git, Node, npm, Docker, and your deploys — runs on the command line you just learned. Head back to the Course Home to keep building on this foundation.
🎉 You command the terminal now!
This is the environment your servers live in. Every tool in the stack sits on top of these commands — you've just learned the ground floor of the whole building.