LINUX
You already live here. This guide sharpens the muscle memory and hands you better tools.
Sahil just got a key. Not a metal one, an SSH key, and behind it sat a small Linux box humming in a closet somewhere, freshly installed, empty, waiting. No graphical desktop. Just a blinking cursor and a prompt that ended in a dollar sign.
That box is the through-line of this guide. Every command below is something Sahil actually needed: to move around, read a file, find a config, fix a permission, kill a runaway process, install a package, reach another machine. We keep the theory thin and the examples real.
If you have used Linux for years, treat this as a refresher with a sharper toolbox bolted on. If you are newer, follow Sahil step by step. Either way, the goal is the same: by the end you should be able to sit at a strange machine and feel at home.
/ the root of everything
|
|-- bin/ core programs (ls, cp, cat)
|-- etc/ system-wide config files
|-- home/
| '-- sahil/ <-- you are (probably) here
|-- var/ logs, spools, things that grow
|-- tmp/ scratch space, wiped on reboot
|-- usr/ installed software
'-- proc/ a live window into the kernel
The Lay
of the Land
First instinct in a new place: figure out where you are standing and what is around you. Three commands answer that, and Sahil types them in the same order almost every time.
$ pwd # print working directory: where am I? /home/sahil $ ls # list what's here $ ls -lah # long view, all files, human sizes $ cd /etc # change directory (absolute path) $ cd .. # up one level $ cd - # jump back to the previous directory $ cd # home, from anywhere
Two ideas do most of the work here. A path starting with / is absolute (measured from root); anything else is relative to where you stand. And the trio . (here), .. (up), and ~ (home) appears everywhere, so it is worth burning in early.
Seeing the tree
To see structure rather than one flat list, tree draws the whole branch. On a big directory it is overwhelming, so cap the depth.
$ tree -L 2 # two levels deep, no deeper $ eza --tree --level=2 # the modern, colorful version eza > tree
Reading &
Writing Files
Sahil needs to peek at a config file, skim a long log, and create a few files and folders. This is the daily bread of working in a shell.
Looking inside
$ cat hosts # dump a whole (small) file $ less syslog # scroll a big file; q to quit, / to search $ head -n 20 log # first 20 lines $ tail -n 20 log # last 20 lines $ tail -f log # follow live, as new lines arrive $ bat hosts # cat with syntax highlight + line numbers bat > cat
Making and moving
$ mkdir -p a/b/c # create nested dirs in one shot $ touch notes.txt # create an empty file (or bump its timestamp) $ cp src.txt dst.txt # copy $ cp -r dir1 dir2 # copy a directory (recursive) $ mv old.txt new.txt # rename OR move (same command) $ rm notes.txt # delete a file $ rm -r dir2 # delete a directory and its contents
Editing in place
Two editors live on nearly every machine. nano is gentle (shortcuts shown at the bottom; Ctrl+O saves, Ctrl+X exits). vim is powerful and modal; the survival fact is that Esc then :wq writes and quits, and :q! quits without saving.
Finding
Things
A week in, Sahil's box has thousands of files. The skill that separates the comfortable from the frustrated is finding things fast: by name, or by what they contain.
By name
$ find . -name "*.conf" # classic: search by filename $ find . -type f -mtime -1 # files changed in the last day $ fd conf # same idea, faster + simpler syntax fd > find $ fd -e conf # by extension
By content
$ grep "timeout" config.yml # find a word in a file $ grep -rn "TODO" . # recursive, with line numbers $ rg "TODO" # ripgrep: recursive by default, very fast rg > grep $ rg -i "error" -g "*.log" # case-insensitive, only .log files
Fuzzy, interactive
When Sahil half-remembers a name, fzf turns any list into a live, type-to-filter picker. Piped together with the tools above it becomes a search cockpit.
$ fd -e md | fzf # pick a markdown file interactively $ vim "$(fzf)" # fuzzy-pick a file, open it in vim
Permissions
& Ownership
Sahil tries to run a script and Linux says Permission denied. This is the moment everyone meets the permission model, and once you can read that string of letters, it stops being mysterious.
- rwx r-x r-- | | | | | | | '-- others: read only | | '------- group: read + execute | '------------ owner: read + write + execute '---------------- type: - file d dir l link read = 4 write = 2 execute = 1 rwx = 4+2+1 = 7 r-x = 4+0+1 = 5 so rwx r-x r-- == 754
Run ls -l and the first column is exactly this string. Three groups of three: what the owner may do, what the group may do, what others may do. Each slot is read (r), write (w), or execute (x).
$ chmod +x deploy.sh # make it executable $ chmod 755 deploy.sh # owner rwx, group/other r-x $ chmod 644 notes.txt # owner rw, everyone else read $ chown sahil file # change owner $ chown sahil:dev file # change owner and group
And then there is sudo: run one command as the superuser (root), the account that can override these rules. It is the difference between a request being denied and being obeyed. Use it deliberately.
Who
You Are
Permissions only make sense once you know who the system thinks you are. A few quick commands answer that, and they are the first thing Sahil checks when something behaves unexpectedly.
$ whoami # your username right now $ id # your user id, group ids, all groups $ groups # which groups you belong to $ sudo -i # become root for a session (careful) $ su - otheruser # switch to another user
Creating users (useradd, passwd) is admin territory you will reach for less often. Knowing it exists, and that id and groups explain most permission surprises, is enough to keep moving.
Processes &
Performance
Something is eating the CPU and the box feels sluggish. Sahil needs to see what is running and, if necessary, stop it. Every program you launch becomes a process with a number, its PID.
$ ps aux # snapshot of every running process $ ps aux | grep node # find a specific one $ top # live, sorted by CPU; q to quit $ htop # top, but readable and scrollable htop > top $ btop # prettier still, with mouse + graphs btop > htop $ kill 4821 # ask process 4821 to stop $ kill -9 4821 # force it (last resort)
Foreground, background, jobs
A long task does not have to block the terminal. Sahil can suspend it, push it to the background, and bring it back.
$ long-task & # start it in the background $ jobs # list backgrounded jobs $ fg %1 # pull job 1 back to the foreground # Ctrl+Z suspends the current task; bg resumes it in the background
Packages &
Software
Sahil needs to install a tool. On Linux you rarely download an installer; instead a package manager fetches software (and its dependencies) from trusted repositories. Which one you use depends on the distro family.
$ sudo apt update # refresh the package list $ sudo apt install ripgrep # install $ sudo apt remove ripgrep # uninstall $ apt search fzf # find a package
$ sudo dnf install ripgrep # Fedora family $ sudo pacman -S ripgrep # Arch family (-S = sync/install) $ paru -S yazi # Arch + AUR helper for community pkgs
The
Network
The box does not live alone. Sahil checks its address, tests whether it can reach the outside world, fetches a file, and connects to another machine.
$ ip a # this machine's network addresses $ ping example.com # can I reach it? Ctrl+C to stop $ ss -tulpn # which ports am I listening on? $ curl -s url # fetch a URL (great for APIs) $ wget url # download a file to disk
Reaching another machine
$ ssh sahil@server # open a remote shell $ scp file.txt sahil@server:~ # copy a file over there $ ssh-keygen -t ed25519 # make a key pair (no more passwords)
Services
& Logs
Long-running programs (a web server, a database, SSH itself) are managed as services by systemd. When something should be running but is not, this is where Sahil looks.
$ systemctl status nginx # is it running? why not? $ sudo systemctl start nginx # start it now $ sudo systemctl enable nginx# start it on every boot $ sudo systemctl restart nginx $ journalctl -u nginx -f # follow this service's logs live
Pipes, Power
& the Shell
This is where Linux stops being a list of commands and starts being a language. The shell lets Sahil connect small tools into one custom tool, on the spot. The idea is plumbing: the output of one command becomes the input of the next.
cat access.log | grep 404 | sort | uniq -c | sort -rn | head
[ read file ] -> [ keep 404s ] -> [ sort ] -> [ count
dupes ] -> [ sort by count ] -> [ top few ]
one line answers: which missing pages were hit the most?
$ cmd1 | cmd2 # pipe: send output of cmd1 into cmd2 $ cmd > out.txt # redirect output into a file (overwrite) $ cmd >> out.txt # append instead $ cmd1 && cmd2 # run cmd2 only if cmd1 succeeded $ cmd1 || cmd2 # run cmd2 only if cmd1 failed $ fd -e log | xargs rm # feed a list as arguments to another cmd
Making it yours
Anything Sahil types often becomes an alias, saved in the shell's config file (~/.bashrc or ~/.zshrc) so it loads every session.
# shortcuts that stick around alias ll='eza -lah' alias gs='git status' # a variable, and using it export EDITOR=vim
Sharper
Tools
Everything above works on a bare machine, and you should know it cold. But Sahil does not stop there. These modern replacements are faster, friendlier, and (mostly) drop-in. Install the few that fit how you work; do not install all of them at once.
ripgrep (rg)
Searches file contents across a whole project in milliseconds. Skips ignored and binary files automatically.
fd
Find files by name with simple syntax and sane defaults. Respects .gitignore.
bat
Prints files with syntax highlighting, line numbers, and git markers. Pages long files for you.
eza
Colorful listings, icons, and a built-in --tree mode. Friendlier ls -lah.
zoxide
Learns your most-used directories. Type z proj and jump there from anywhere.
fzf
Turns any list into a live, type-to-filter picker. Pipe anything into it.
btop
A live system monitor with graphs, mouse support, and a layout that is actually readable.
dust
Shows what is eating your disk as an instant, sorted visual tree.
tldr
Community cheat-sheets. tldr tar gives the five examples you actually wanted.
yazi
A blazing terminal file manager with previews. Browse, rename, and move with the keyboard.
zsh + starship
A better shell and a fast, informative prompt. Autosuggestions and git status, built in.
ghostty
A fast, GPU-accelerated terminal with sane defaults. The window Sahil actually types into.
hyprland
For when the desktop itself becomes keyboard-driven. Tiling, scriptable, Wayland-native.
delta
Side-by-side, syntax-highlighted git diffs that are genuinely pleasant to read.
Field
Test
Answer out loud before you open each one. If you can explain it to Sahil, you know it.
Q1What does rwxr-xr-- mean, and what is it as a number?+
754. Read=4, write=2, execute=1, added per group of three.Q2You need to watch a log file as new lines appear. Which command?+
tail -f /path/to/log. The -f means "follow". For a service under systemd, journalctl -u <name> -f does the same.Q3What is the difference between > and >>?+
> overwrites the file with the command's output. >> appends to the end, keeping what was already there.Q4A process with PID 9001 is stuck. What is the difference between kill 9001 and kill -9 9001?+
kill sends a polite signal asking the process to shut down cleanly. kill -9 forces termination immediately with no cleanup. Try the polite one first.Q5Read this aloud: make && ./run || echo failed+
make. If it succeeds, run ./run. If either of those fails, print "failed". && chains on success, || chains on failure.Q6You want every file containing the word "timeout" under the current folder. Bare tools, then the sharp one.+
grep -rn "timeout" . Sharp: rg "timeout" (recursive by default, faster, skips junk).Hands
On
Sahil's box needs tidying. Do these on a real machine (or a throwaway container). Hints point you at the right tool; the exact incantation is yours to assemble. That is the part that builds memory.
- From your home directory, create a folder
lab/with three nested subfolders inside it, using a single command. Hint: onemkdirflag turns a path into all the directories along it. - Create an empty file
lab/log.txt, then make it readable and writable by you but read-only for everyone else. Hint:touch, then a three-digitchmod. Recall the number for "owner read+write, others read". - Find every
.conffile under/etcand count how many there are. Hint:fd(orfind) produces the list; pipe it intowc -lto count lines. - Search all of
/etcfor any file containing your username, ignoring case, without drowning in permission-denied noise. Hint:rgwith a case-insensitive flag; it already skips what it cannot read. - Start a process that just waits (for example
sleep 300) in the background, confirm it is running, then stop it by its PID. Hint: trailing&, thenjobsorps, thenkill. - In one line, take a log file, keep only the lines containing "error", and write them to
errors.txt. Hint:grep(orrg) piped or redirected with>. - Add one alias to your shell config that you would genuinely use, then reload the config without opening a new terminal.
Hint: edit
~/.bashrcor~/.zshrc, thensourceit. - Stretch: install one tool from the Sharper Tools section with your package manager, and replace one habit with it for a day.
Hint:
rgorfdare the easiest wins to start with.