Fifty commands is a lot to hand someone on day one. So before the list, the useful thing to know is that you don’t need fifty. You need about ten to get around, and the other forty arrive naturally as you hit problems that need them.
This list is grouped by what you’re actually trying to do rather than alphabetically, because nobody sits down thinking “I need a command starting with d”. Most entries include real output, since a command you’ve never seen the output of isn’t a command you know yet.
Start with these ten
If you learn nothing else this week, learn these. They cover moving around, looking at things, and not getting stuck.
pwd where am I
ls what is here
cd go somewhere
cat show me this file
less show me this long file
mkdir make a directory
cp copy
mv move or rename
rm delete
man read the manual for any of the above
Use those for a few days on real tasks. Poke around /etc, make a directory, copy something into it, read a config file. The rest of the list will make more sense once your hands know these.
The full list at a glance
| Command | What it does |
|---|---|
pwd |
Print the directory you’re in |
ls |
List files |
cd |
Change directory |
tree |
Show a directory as a tree |
cat |
Print a file to the screen |
less |
Page through a long file |
head |
First lines of a file |
tail |
Last lines, or follow a live log |
wc |
Count lines, words, bytes |
touch |
Create an empty file or update its timestamp |
mkdir |
Create directories |
cp |
Copy files and directories |
mv |
Move or rename |
rm |
Delete |
ln |
Create links, usually symlinks |
find |
Search the filesystem by name, size, age |
grep |
Search inside files |
which |
Show which binary a command runs |
history |
List commands you’ve already run |
echo |
Print text or a variable |
nano |
Edit a file without learning vim first |
chmod |
Change permissions |
chown |
Change owner and group |
sudo |
Run one command as root |
ps |
List running processes |
top |
Live view of what’s using the machine |
kill |
Signal or stop a process |
df |
Free space per filesystem |
du |
Space used by directories |
free |
Memory in use |
lsblk |
List disks and partitions |
whoami |
Which user you are right now |
id |
Your UID, GID and groups |
uname |
Kernel and architecture |
uptime |
How long the box has been up, plus load |
date |
System date and time |
hostname |
The machine’s name |
ip |
Addresses, routes, interfaces |
ss |
Sockets, ports, connections |
ping |
Can I reach that host |
curl |
Talk to a URL from the shell |
wget |
Download a file |
ssh |
Log into another machine |
scp |
Copy a file over SSH |
rsync |
Sync directories, locally or remotely |
tar |
Bundle and extract archives |
apt |
Install packages on Debian and Ubuntu |
dnf |
Install packages on RHEL, Rocky, Alma, Fedora |
systemctl |
Start, stop and inspect services |
man |
The manual for everything above |
Getting your bearings
pwd answers the only question that matters when you’re lost.
$ pwd
/home/asif/projects
ls is the one you’ll type most in your life. Plain ls is fine, but ls -lh is the version worth building into muscle memory. Long format, human-readable sizes.
$ ls -lh
total 24K
drwxr-xr-x 2 asif asif 4.0K Sep 8 09:14 backups
-rw-r--r-- 1 asif asif 18K Sep 8 09:12 notes.md
-rwxr-xr-x 1 asif asif 412 Sep 7 17:40 deploy.sh
Add -a to include hidden files, the ones starting with a dot. Half of what configures your shell lives in those, so ls -lah is the habit to form.
cd moves you. Three shortcuts are worth more than the command itself: cd alone goes home, cd - goes back to where you just were, and cd .. goes up one.
tree shows structure at a glance. Usually needs installing, and -L 2 stops it printing your entire disk.
$ tree -L 2
.
|-- backups
| `-- 2026-09-07
|-- deploy.sh
`-- notes.md
If the layout of the filesystem itself is unfamiliar, Linux commands and directory structure covers what lives where and why.
Reading files
cat dumps a whole file to the screen. Perfect for short files, painful for long ones.
less is what you want for anything longer than a screen. Arrow keys scroll, / searches, q quits. That’s genuinely all you need to know to start.
head and tail take the ends. tail is the more useful of the pair because of one flag:
tail -f /var/log/syslog
That follows the file as it grows. Leave it running in one window while you reproduce a problem in another and you’ll watch the error appear as it happens. It’s the single most useful troubleshooting habit on this page.
wc counts. wc -l for lines is the version you’ll use, usually on the end of a pipe to answer “how many”.
$ grep -c error /var/log/syslog
14
Creating, copying and deleting
touch creates an empty file, or bumps the timestamp on one that exists.
mkdir makes directories. -p creates parents as needed and doesn’t complain if things already exist, which is why scripts use it:
mkdir -p /srv/app/config/nginx
cp copies. Directories need -r. mv both moves and renames, because on Linux renaming is just moving a file to a new name in the same place.
rm deletes, and there’s no recycle bin. rm -r for directories. Two things to internalise early:
rm -i important.conf # asks before each delete
rm -rf /path/to/thing # no questions, no undo
The dangerous part isn’t rm -rf itself, it’s rm -rf with a variable or a wildcard that isn’t what you assumed. Get in the habit of running ls on the exact path first. Same path, different command, and you see precisely what’s about to disappear.
ln -s makes a symbolic link, a pointer to something else. They’re everywhere in Linux, particularly in service configuration.
ln -s /srv/app/current/config.yml /etc/app/config.yml
Finding things
find searches by attributes. It has a reputation for awkward syntax, but three patterns cover most real use:
find . -name "*.log" # by name, from here down
find /var -size +100M # anything over 100MB
find . -mtime -1 # changed in the last day
grep searches inside files, and it’s the one you’ll lean on hardest. Recursive, case-insensitive, with line numbers:
$ grep -rni "timeout" /etc/nginx/
/etc/nginx/nginx.conf:36: keepalive_timeout 65;
/etc/nginx/conf.d/app.conf:12: proxy_read_timeout 300;
which tells you which binary actually runs when you type a name. Handy when a command behaves differently than you expect, usually because there are two versions installed.
history lists what you’ve run. The better trick is Ctrl+R, which searches your history as you type. Learn that one keystroke and you’ll stop retyping long commands forever.
Permissions and running as root
chmod changes permissions. The numbers look cryptic until you know they’re just three bits per group: read is 4, write is 2, execute is 1.
chmod 644 file.txt # owner read/write, everyone else read
chmod 755 script.sh # same, plus everyone can execute
chmod +x script.sh # just make it runnable
You’ll see chmod 777 suggested in forum answers as a fix for permission errors. It works the way removing your front door fixes a stiff lock. It means anyone on the system can read, change or run that file, and it usually hides the real problem, which is ownership.
chown changes who owns a file, which is more often the actual fix:
sudo chown -R www-data:www-data /var/www/html
When plain owner and group permissions aren’t enough, ACLs give per-user rules. That’s covered in Linux ACLs with setfacl and getfacl.
sudo runs a single command as root. The habit worth building is using sudo for the one command that needs it rather than becoming root and staying there, because most bad afternoons start with a root shell left open in the wrong window.
sudo systemctl restart nginx
sudo !! # rerun your last command with sudo
Processes
ps lists processes. ps aux is the incantation everyone memorises, usually piped into grep:
$ ps aux | grep nginx
root 1240 0.0 0.1 55180 2108 ? Ss 09:02 0:00 nginx: master process
www-data 1241 0.0 0.3 55832 6284 ? S 09:02 0:00 nginx: worker process
top is the live version. Sorted by CPU by default, press M to sort by memory, q to quit. If htop is available it’s friendlier, but top is on every machine you’ll ever touch, so learn it first.
kill sends a signal to a process by PID. Default is a polite request to shut down. -9 is the one that can’t be refused, and it’s a last resort because the process gets no chance to clean up.
kill 1241 # ask nicely
kill -9 1241 # force it
Disk and memory
df -h shows free space per filesystem. First command to run when something says “no space left on device”.
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 40G 31G 7.2G 82% /
/dev/sdb1 100G 45G 50G 48% /var/lib/docker
tmpfs 2.0G 0 2.0G 0% /dev/shm
du tells you what’s eating it. This is the pattern to remember, because it finds the biggest offenders in one line:
$ sudo du -h --max-depth=1 /var | sort -rh | head -5
28G /var/log
12G /var/lib
2.1G /var/cache
440M /var/www
Nine times out of ten on a full server it’s /var/log, and the fix is log rotation rather than deleting things by hand.
free -h shows memory. The number that confuses everyone is “available” versus “free”. Linux deliberately uses spare RAM for disk cache, so low free memory is normal and healthy. Read the available column instead, and there’s more on this in understanding the free command.
$ free -h
total used free shared buff/cache available
Mem: 3.8Gi 1.2Gi 220Mi 48Mi 2.4Gi 2.3Gi
Swap: 2.0Gi 0B 2.0Gi
lsblk lists block devices as a tree, which is how you work out what disk is what before touching partitions.
Who and what you are
$ whoami
asif
$ id
uid=1000(asif) gid=1000(asif) groups=1000(asif),27(sudo),999(docker)
$ uname -r
6.8.0-45-generic
$ uptime
09:31:44 up 42 days, 3:18, 2 users, load average: 0.14, 0.09, 0.03
$ hostname
web01
id earns its place because group membership explains a lot of permission problems. Being in the docker group above is why that user can run containers without sudo.
On uptime, the three load numbers are averages over 1, 5 and 15 minutes. Compare them to your CPU core count. A load of 4.0 on a 4-core box is fully busy, while the same number on a 16-core box is quiet.
date prints the time, and matters more than it looks when you’re reading logs across servers in different timezones.
Networking
ip replaced ifconfig. The short form is the one to know:
$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
enp0s3 UP 192.168.1.42/24 fe80::a00:27ff:fe4e:66a1/64
If the prefix notation there is unfamiliar, IP addressing and subnetting covers what the /24 is telling you.
ss replaced netstat and shows what’s listening:
$ ss -tulpn | head -4
Netid State Local Address:Port Process
tcp LISTEN 0.0.0.0:22 users:(("sshd",pid=894,fd=3))
tcp LISTEN 0.0.0.0:80 users:(("nginx",pid=1240,fd=6))
tcp LISTEN 127.0.0.1:3306 users:(("mariadbd",pid=1102,fd=21))
That output answers “is my service actually running and on which interface”. Note the difference between 0.0.0.0:80, reachable from anywhere, and 127.0.0.1:3306, reachable only from the machine itself. More in the ss command guide.
ping checks reachability. If ping works but a name doesn’t resolve, your problem is DNS, not the network.
curl talks to URLs. Beyond fetching pages, it’s how you check whether a web service is healthy:
curl -I https://example.com # headers only
curl -s -o /dev/null -w "%{http_code}" https://example.com
wget downloads files. Simpler than curl for grabbing something and saving it, and better at resuming interrupted downloads.
ssh logs you into other machines, and if you administer anything remote it becomes your most used command. Setting up keys so it stops asking for passwords is covered in passwordless SSH, rsync and scp.
Moving files around
scp copies over SSH. Fine for one file, though worth knowing OpenSSH has been steering people away from it.
rsync is the better tool for anything repeated. It transfers only what changed, resumes cleanly, and preserves permissions:
rsync -av /home/asif/docs/ /backup/docs/
Watch the trailing slash on the source, which changes the meaning. Full detail in the rsync guide.
tar bundles files. Two lines cover almost everything:
tar -czvf backup.tar.gz /path/to/dir # create
tar -xzvf backup.tar.gz # extract
The letters are create, gzip, verbose, file. Extract swaps the c for an x. If you can remember “czvf to squeeze, xzvf to open” you’re done.
Packages and services
apt on Debian and Ubuntu, dnf on RHEL, Rocky, AlmaLinux and Fedora.
sudo apt update && sudo apt install nginx
sudo dnf install nginx
The apt update step refreshes the package list. Skipping it is why “package not found” happens on an otherwise fine system.
systemctl controls services. Four subcommands cover daily work:
sudo systemctl start nginx
sudo systemctl enable nginx # start automatically at boot
systemctl status nginx
sudo systemctl restart nginx
start and enable are different things, and mixing them up is a classic. Start runs it now. Enable makes it come back after a reboot. A service that works until the machine restarts is almost always one that was started but never enabled.
Getting unstuck
man is the manual, offline, on every machine.
man ls
It opens in less, so / searches and q quits. Man pages are dense and written as reference rather than tutorial, so don’t read them start to finish. Search for the flag you’re wondering about.
Two faster alternatives when you just want an example. Most commands accept --help for a short summary, and tldr gives practical examples instead of a specification, though you’ll need to install it.
Keys that matter more than commands
| Keys | What it does |
|---|---|
Tab |
Completes filenames and commands. Use constantly. |
Ctrl+C |
Stop whatever is running |
Ctrl+R |
Search your command history |
Ctrl+L |
Clear the screen |
Ctrl+D |
End input, or log out |
!! |
Repeat the last command |
Tab completion is the highest-value item on this entire page. It saves typing, but more importantly it confirms the path exists before you commit to a command. If Tab won’t complete it, you typed it wrong.
Commands people still teach that you shouldn’t learn
| Old | Use instead |
|---|---|
ifconfig |
ip addr |
netstat |
ss |
route |
ip route |
service |
systemctl |
yum |
dnf |
The old ones often still work through compatibility shims, which is exactly why they persist in tutorials. But they’re not installed by default on current releases, so a guide that opens with ifconfig is telling you how old it is.
The five that can ruin your day
| Command | Why it bites |
|---|---|
rm -rf |
No confirmation, no undo. Check the path with ls first. |
chmod -R 777 |
Opens a file or tree to everyone and hides the real problem. |
dd |
Writes raw to a device. One wrong letter overwrites the wrong disk. |
mkfs |
Formats. Instantly. |
> on a file |
cmd > file truncates it before running. >> appends. |
None of these are commands to avoid. They’re commands to slow down for. The pattern in almost every one of these accidents is a path or a device name that wasn’t what the person assumed, so the fix is always the same: look at the target before you act on it.
How to actually learn these
Don’t memorise the list. It won’t stick, and you’ll be looking things up regardless, which is what everyone does including people who have run Linux for twenty years.
Give yourself a machine you’re allowed to break. A cheap VPS or a local VM, not the laptop you need tomorrow. Then use real tasks as the excuse to reach for commands: install a web server, break it, read the logs with tail -f, find the config with find, fix it with nano, restart it with systemctl. That single loop uses a dozen commands off this list and you’ll remember all of them, because you needed them for something.
The ten at the top, plus Tab and Ctrl+R, will carry you further in your first month than memorising all fifty ever would.


