Docudjeex
Linux tips for dummies

Command line basics

Understand how a Linux command is built, learn the essential terminal commands, what their names mean, and get a cheat sheet to keep at hand.

A server has no desktop, no icons and no mouse. Everything happens in a terminal, and that black window with a blinking cursor is the single thing that puts people off self-hosting. It shouldn't: the terminal is just a conversation. You type one line, the machine does exactly that and answers. Nothing more magic than a search bar, except it does far more and never hides an option behind three menus.

The good news is that you don't need to know a hundred commands. Ten of them cover almost everything you'll do on a home server, and they all follow the same pattern. Learn the pattern first, and every command you meet later becomes readable, even the ones you've never seen.

How a command is built

Every command line, without exception, is the same sentence: what to run, how to run it, what to run it on.

Anatomy of a command
sudo apt install -y nano
│    │   │       │  └─ argument: what the command works on
│    │   │       └──── option: changes how it behaves
│    │   └──────────── subcommand: what the program should do
│    └──────────────── the program you're running
└───────────────────── run it with administrator rights

Read out loud, that line says "as an administrator, ask the package manager to install the nano package, and don't ask me to confirm". Spaces are what separate the pieces, which is why a folder named My Backups has to be quoted (cd "My Backups") or the shell reads it as two different things.

Options, short and long

Options change how a command behaves. They come in two flavours, and most commands accept both:

  • Short, a single dash and a single letter: ls -a. They can be stacked, so ls -l -a -h is usually written ls -lah.
  • Long, two dashes and a whole word: ls --all. Longer to type, but you can still tell what it does six months later, which is why they're the better choice in a script.

Some options expect a value right after them: ssh-keygen -t ed25519 (-t for type), rsync --exclude @eaDir. And case matters, always. In ls, -r reverses the sort order while -R walks into subfolders. Two different things, one letter apart.

Arguments and paths

The argument is the target: a file, a folder, a package name, an address. Many commands accept several at once, separated by spaces, which is what makes the terminal fast: rm file1.txt file2.txt file3.txt deletes three files in one go.

When the target is a place on the disk, you write it as a path, and there are a few shortcuts worth knowing:

PathMeans
/the root of the whole system, everything lives under it
~your own home folder, /home/username
.the folder you're currently in
..the folder just above
/var/logan absolute path, same result from anywhere
logs/todaya relative path, understood from where you currently stand

Which folder holds what is a subject of its own, covered in folders and partitions.

The prompt itself tells you where you are: in username@serveex:~/docker$, you're logged in as username on the machine named serveex, inside the docker folder of your home. That final $ means a normal user. If it ever shows #, you're root and every typo counts double.

Getting help

Two habits make you independent from tutorials. command --help prints a quick summary of every option, and man command opens the full manual (man for manual), which you leave by pressing Q.

Tip: three keyboard habits that change everything: Tab completes the file or folder name you started typing, so you almost never type a full path; the Up arrow brings back your previous commands, which saves retyping a long line for one character; and Ctrl + C stops whatever is currently running.

Chaining commands

Once the pattern clicks, commands can be plugged into each other:

  • && runs the next one only if the previous one succeeded: sudo apt update && sudo apt full-upgrade
  • |, the pipe, feeds the output of one command into another: ls -l | grep backup lists the folder, then keeps only the lines containing "backup"
  • > writes the output into a file instead of the screen, and >> adds to the end of that file: df -h > disk-report.txt

The commands you'll actually use

Most command names are abbreviations of an English phrase. Once you know what they stand for, they stop looking like keyboard noise.

pwd, print working directory

Tells you where you are. It changes nothing, it just answers the question.

Terminal
pwd
Output
/home/username/docker

ls, list

Lists what's in the current folder. On its own it prints bare names, so it's almost always used with options: -l for the long format with sizes, dates and permissions, -a to also show hidden files (the ones starting with a dot), -h for sizes in K/M/G instead of raw bytes.

Terminal
ls -lah
Output
total 20K
drwxr-xr-x  4 username username 4.0K Sep  5 10:12 .
drwxr-xr-x 18 username username 4.0K Sep  4 21:03 ..
-rw-r--r--  1 username username  512 Sep  5 10:12 .env
-rw-r--r--  1 username username 1.2K Sep  5 09:58 compose.yaml
drwxr-xr-x  3 username username 4.0K Sep  2 18:44 immich

The first column is the permissions, d at the very start meaning it's a folder. Then the owner, the size, the date of the last change, and the name.

cd, change directory

Moves you around. With a path it goes there, with .. it goes up one level, and with nothing at all it takes you back home.

Terminal
username@serveex:~/docker$ cd /var/log
username@serveex:/var/log$ cd ..
username@serveex:/$ cd
username@serveex:~$

Notice the prompt following you around: it always shows where you currently stand, so you rarely need pwd in practice.

mkdir, make directory

Creates a folder. Several at once if you list them, and -p creates the whole chain of parents in one shot, which is the version you'll actually use.

Terminal
mkdir backups
mkdir -p docker/immich/config
Output

Nothing. That's not a bug, it's the rule: most commands say nothing when they succeed and only speak up when something goes wrong. Silence is good news, and ls confirms the folder is there.

cp and mv, copy and move

cp copies, mv moves. Same shape both times: first the source, then the destination. Copying a folder needs -r, for recursive, since a folder means everything inside it too. mv doubles as the rename command, because renaming a file is just moving it to a new name.

Terminal
cp compose.yaml compose.yaml.bak
cp -r config/ config-backup/
mv old-name.txt new-name.txt
ls
Output
compose.yaml  compose.yaml.bak  config  config-backup  new-name.txt

Three silent commands, and ls showing the result: the copy sits next to the original, the folder was duplicated, and old-name.txt is gone because moving it to another name is exactly what renaming means.

rm, remove

Deletes. There is no recycle bin, no undo, no confirmation dialog. -r deletes a folder and its contents, -f forces without asking.

rm -rf is the command that wipes homelabs. It doesn't check, doesn't warn, and doesn't stop. Read the path twice before pressing Enter, especially when the line starts with sudo and contains a / or a *. You can also prevent this by wrapping sudo in a small Bash function that asks "are you sure?" before it lets an rm through, covered in rm confirmation guard.

cat and nano, read and edit

cat (short for concatenate) dumps a whole file to the screen, perfect for a short config. For anything longer, less scrolls through it (named as a joke on more, the older pager it replaced), and you quit it with Q.

To actually change a file, nano opens a simple editor: arrows to move, Ctrl + O to save, Ctrl + X to leave.

Terminal
cat .env
Output
PUID=1000
PGID=1000
TZ=Europe/Paris

grep, search inside files

grep stands for global regular expression print, which is a mouthful for "find me this text". You give it what to look for and where, and it prints every matching line. -r searches a whole folder, -i ignores upper and lower case, -n shows line numbers.

Terminal
grep -rin "password" /home/username/docker
Output
/home/username/docker/immich/.env:6:DB_PASSWORD=changeme
/home/username/docker/vaultwarden/compose.yaml:14:  ADMIN_PASSWORD=hunter2

Each line is the file, then the line number inside it, then the matching line itself. Very handy for the day you can't remember which stack holds a setting.

sudo, run as administrator

Substitute user do. A normal user can't touch the system's files, which is exactly what protects you from wrecking the machine by accident. Prefixing a command with sudo runs that single command with administrator rights, and asks for your password the first time.

Terminal
nano /etc/ssh/sshd_config
Output
Error writing /etc/ssh/sshd_config: Permission denied
Terminal
sudo nano /etc/ssh/sshd_config
Output
[sudo] password for username:
If a command answers Permission denied, that's usually the whole problem: it needed sudo. Resist the reflex of putting sudo on everything though, a file created as root will keep annoying you afterwards because your normal user no longer owns it.

Cheat sheet

The ones worth keeping at hand, and where their names come from.

CommandShort forWhat it does
pwdprint working directoryShows where you are
lslistLists files and folders
cdchange directoryMoves you somewhere else
mkdirmake directoryCreates a folder
touchplain EnglishCreates an empty file, or refreshes its date
cpcopyCopies a file or folder
mvmoveMoves or renames
rmremoveDeletes, permanently
catconcatenatePrints a file to the screen
lessa pun on moreScrolls through a long file
nanothe editor replacing PicoEdits a file
grepglobal regular expression printSearches for text
findplain EnglishSearches for files by name, size or date
manmanualOpens a command's full documentation
dfdisk freeShows free space per partition
lsblklist block devicesDraws the tree of disks and partitions
dudisk usageShows what a folder weighs
psprocess statusLists running processes
htopHisham's topLive view of CPU, RAM and processes
killplain EnglishStops a process by its number
chmodchange modeChanges a file's permissions
chownchange ownerChanges who owns a file
sudosubstitute user doRuns one command as administrator
aptadvanced package toolInstalls, updates and removes packages
systemctlcontrol systemdStarts, stops and enables services
sshsecure shellOpens a session on a remote machine
scpsecure copyCopies files over SSH
tartape archivePacks and unpacks archives
wgetweb getDownloads a file from a URL
curlclient URLSends a request to a URL
historyplain EnglishLists the commands you typed before
Tip: nobody memorises this. You'll look up the same three options for weeks, then one day realise you're typing them without thinking. Until then, --help and this table are perfectly legitimate.
Contributor:Djeex
Copyright © 2026