cd ..
LINUX

Surviving the Shell: From FHS to Diff, the Linux You Use Every Day

These are my notebook notes as I deep-dive into Linux — part of LINUXtips’ Linux for Cloud Native course, within the PICK 2026 track. I’ve tidied everything up here because writing is the best way to solidify knowledge, and because one day this will become a quick reference when I can’t remember a flag.

This post is long on purpose: it’s a complete map of what you type every day in the terminal, from ls to diff.

First Steps

Two references that appear everywhere:

ls -lha /bin/ls   # lista o arquivo ls, que está dentro de /bin

And direct kernel reading via /proc:

cd /proc
cat meminfo    # situação da memória RAM e swap
cat cpuinfo    # dados do processador

The cpuinfo shows:

In Linux, Everything is a File

It’s not a slogan, it’s literal:

That’s why cat, grep, and redirection work on virtually everything. You don’t need an API to query memory — you just need to read a file.

Directory Tree and the FHS

In Linux, there is a single root: /. Everything stems from it. No matter how many disks, partitions, or devices you have — all will be mounted at some point within this tree. No C:, D:, E:.

This structure follows the FHS (Filesystem Hierarchy Standard) standard:

DirectoryWhat it is
/The root of everything. The starting point of the entire tree
/homeUsers’ personal directories. If your user is devops, it will be /home/devops. The ~ shortcut represents yours
/etcWhere system configuration resides: /etc/ssh/sshd_config, /etc/hostname, /etc/passwd
/varStores frequently changing data, such as in /var/log
/tmpTemporary directories
/usrContains programs, libraries, and documentation installed by the system
/bin and /sbinStore essential binaries. In modern distros, they usually point to directories within /usr
/proc and /sysAre virtual filesystems generated in real-time by the kernel. They display information about processes, memory, CPU, drivers, and the kernel
/devContains device files. This is also where the famous /dev/null, Linux’s black hole, is located
/mnt and /mediaMount points for external devices
/optThird-party software, installed outside the package manager

FHS Detail: the fact that /bin and /sbin are symlinks to /usr is a result of the usr-merge, adopted by most distros in the last decade. Run ls -l /bin on a recent Fedora or Ubuntu and you’ll see the arrow.


Reading ls -l

ls -l   # mostra detalhes: permissões, dono, tamanho, data etc.

A typical line:

drwxr-xr-x  4  root  root  4096  Abr 15 16:09  cache
│└┬┘└┬┘└┬┘  │   │     │     │       │            │
│ │  │  │   │   │     │     │       │            └─ nome
│ │  │  │   │   │     │     │       └────────────── data de modificação
│ │  │  │   │   │     │     └────────────────────── tamanho
│ │  │  │   │   │     └──────────────────────────── grupo
│ │  │  │   │   └────────────────────────────────── dono
│ │  │  │   └────────────────────────────────────── nº de links
│ │  │  └────────────────────────────────────────── permissões: outros
│ │  └───────────────────────────────────────────── permissões: grupo
│ └──────────────────────────────────────────────── permissões: dono
└────────────────────────────────────────────────── tipo

The first character is the type:

The next nine are three rwx (read, write, execute) blocks for owner, group, and others.

Directory Manipulation

ls — list content

CommandWhat it does
ls -aLists all files, including hidden ones (those starting with .)
ls -lProvides details: permissions, owner, size, date
ls -hMakes the size “human-readable”: 1K, 20M, 2G instead of a huge number
ls -SSorts by size
ls -tOrders by modification date
ls -FAdds a separator to identify types (/ directory, * executable, @ link)
ls -iShows the inode number
ls -RLists recursively
ls --color=autoUses colors to differentiate file types, but only when the output is being displayed directly in the terminal

The combination I use by reflex:

ls -lha    # detalhado + ocultos + tamanho legível

The --color=auto detail is more interesting than it seems: if you do ls | grep something, the output doesn’t go to the terminal, it goes to the pipe — and ls automatically turns off colors. That’s why ANSI escape codes don’t leak into your grep.

mkdir — create directories

mkdir diretorio
mkdir -p gitopops/produtos/checkout   # cria todos os diretórios intermediários

The -p means parents: it creates the necessary “parent” directories in the path. Even if gitopops doesn’t exist yet, it creates it first and then goes down. Bonus: with -p, the command doesn’t fail if the directory already exists — that’s why it appears in so many automation scripts.

rmdir — remove empty directories

rmdir pasta_vazia
rmdir -p Pasta2/Pasta2_2   # remove Pasta2_2 e tenta remover os pais, se ficarem vazios

The rmdir only removes empty directories. It’s a protection, not a limitation.

cd, tree, and touch

File Manipulation

cp — copying

Syntax: cp [source] [destination]

cp original.txt copia.txt               # copiando um arquivo
cp original.txt /tmp/                    # copiando um arquivo para um diretório
cp -r projetos/ /tmp/backup-projetos/    # copiando um diretório inteiro (obrigado usar -r)
FlagWhat it does
-vVerbose: shows on screen what is being copied
-r / -RRecursive — mandatory for directories
-aArchive mode: preserves permissions, links, and timestamps
-nCopies without overwriting what already exists
-uCopies only if the source is newer than the destination
-sCreates symbolic links instead of copying

mv — moving and renaming

In Linux, moving and renaming are the same operation:

mv relatorio.txt /tmp/                                          # move para outro diretório
mv relatorio.txt relatorio-final.txt                            # renomeia
mv /tmp/relatorio.txt /home/devops/documentos/relatorio-v2.txt  # move e renomeia de uma vez

rm — removing

rm arquivo-inutil.txt      # remove um arquivo
rm -r pasta-antiga/        # remove um diretório e tudo dentro dele
rm -rf pasta/              # força a remoção, sem confirmação

The -r is recursive: it enters all subfolders and removes everything — files, subdirectories, files within subdirectories.

The -f is force: it doesn’t ask for confirmation, doesn’t complain if the file doesn’t exist. It simply deletes everything silently.

⚠️ Exercise extreme caution with rm -rf. It doesn’t ask for confirmation, there’s no trash can, and no undo. Before running with glob (*), replace rm with ls and check exactly what would be deleted.

Wildcards

What if you want to copy all .log files? Or delete all .tmp files? For this, wildcards exist — patterns that the shell expands into filenames before the command even runs.

* — anything (zero or more characters)

ls /etc/*.conf              # todos os .conf em /etc
cp *.log /tmp/backup-logs/  # copia todos os .log do diretório atual
rm /tmp/*.tmp               # remove todos os .tmp de /tmp

The * is the most used. It replaces any sequence of characters:

? — exactly one character

ls arq_?.txt     # arq_1.txt, arq_a.txt — mas não arq_10.txt
ls arq_??.txt    # arq_10.txt, arq_ab.txt

[ ] — a character within a set or range

ls m[a-c]*       # arquivos que começam com m e cuja segunda letra vai de a até c
ls arq_[123].txt # arq_1.txt, arq_2.txt, arq_3.txt

which — where is the binary?

which python3    # mostra o caminho do executável que o shell vai chamar

Archiving and Compressing

# Criar
tar -czf gitopops.tar.gz projetos/
#      │││
#      ││└─ file: nome do arquivo
#      │└── compactar (gzip)
#      └─── criar

# Ver o conteúdo sem extrair
tar -tf gitopops.tar.gz

# Extrair
tar -xzf backup-projeto.tar.gz

Mnemonic rule: create, extract, list — always accompanied by -f (file). -z is gzip; use -j for bzip2 and -J for xz.

It’s a pointer to a path of another file. If the original file is moved or deleted, the link breaks.

# Criando um link simbólico
ln -s /etc/nginx/nginx.conf ~/nginx-config

# Verificando
ls -l ~/nginx-config
lrwxrwxrwx 1 devops devops 23 Feb 16 10:30 nginx-config -> /etc/nginx/nginx.conf

The l at the beginning indicates a symbolic link. The arrow shows where it points. When you run vim ~/nginx-config, you’ll be editing the original file at /etc/nginx/nginx.conf.

It points directly to the data on disk (the inode), not to the path. If the original file is renamed or moved within the same filesystem, the hard link continues to work. But it cannot point to a directory or cross different filesystems.

# Criando um hard link
ln /etc/hostname ~/hostname-link

# Ambos apontam para o mesmo inode
ls -li /etc/hostname ~/hostname-link

The -i from ls shows the inode number — if it’s the same for both, it’s the same physical file with two names.

Viewing and Editing Text

cat — straight to the point

The cat (concatenate) dumps the entire content of a file to the terminal, all at once.

cat /etc/hostname

It’s perfect for small files: a hostname, a public key, a configuration file with a few lines. But if you run cat on a 10,000-line file, the output will flood the terminal and you’ll lose control of what you’re reading. For that case, use less.

FlagWhat it does
cat -nNumbers all lines
cat -bNumbers only lines with text
cat -EShows $ at the end of each line
cat -TShows TAB as ^I
cat -n /etc/ssh/sshd_config

This is gold when someone says “the error is on line 47” and you need to go straight to the point without counting lines manually.

-E and -T save lives when you’re hunting for invisible whitespace or bizarre line endings in a config file.

cat with multiple files: if you pass more than one name, it concatenates (hence the name) the output:

cat /etc/hostname /etc/os-release

Shows the content of both files, one after the other. It seems simple, but it’s the basis for many redirection operations.

Compressed cousins:

CommandWhat it does
zcatReads .gz file without decompressing
bzcatReads .bz2 file without decompressing
xzcatReads .xz file without decompressing

Reversing:

tac arquivo.txt      # mostra o arquivo de baixo para cima
tac -s "," arquivo   # inverte usando um separador específico

echo and redirection

echo "Texto" > arquivo.txt     # sobrescreve
echo "Texto" >> arquivo.txt    # anexa ao final

less — controlled navigation

The less command opens the file in paged mode, without dumping everything to the screen at once. You navigate calmly:

less /var/log/syslog

The navigation commands within less are essential:

KeyWhat it does
/termStarts a search
nAdvances to the next occurrence
NGoes back to the previous occurrence
GJumps to the end of the file
gGoes back to the beginning
spaceAdvances a full page
bGoes back a full page
qExits

The less command is the default pager for several commands. When you run man ssh to read the SSH manual, the content opens in less. The same shortcuts work inside. Knowing how to navigate in less is knowing how to navigate all of Linux’s documentation.

A powerful flag is less +F, which transforms less into follow mode — equivalent to tail -f, but with the advantage of being able to pause with Ctrl+C, navigate through the file, and then resume the flow with F.

less +F /var/log/syslog

more

It also pages, but without the ability to go back. less is strictly superior. (Yes, that’s the joke: less is more.)

head and tail — surgical cuts

The head command shows the first lines of a file (10 by default):

head /etc/passwd

The tail command shows the last:

tail /var/log/syslog

To specify how many lines you want to see, use the -n flag:

head -n 5 /etc/passwd
tail -n 50 /var/log/auth.log

The head command is great for quickly viewing the structure of a configuration file without loading the entire thing. tail, on the other hand, is indispensable for logs, because the most recent information is always at the end.

tail -f — the real-time log monitor

This is one of the commands we’ll use most in our careers. tail -f (follow) doesn’t just show the last lines: it stays open and shows new lines as they are written to the file.

tail -f /var/log/syslog

The terminal becomes a live log monitor. While tail -f is running, any service that writes to syslog appears instantly on the screen. This is how you investigate problems in real-time: open the log and observe what’s happening while you reproduce the error.

Combining with grep filters only what you’re interested in:

tail -f /var/log/auth.log | grep "Failed password"

Now you only see failed login attempts, in real-time. Perfect for detecting brute-force attacks on SSH, for example.

The | (pipe) takes the output of one command and feeds it as input to the next. To exit tail -f, press Ctrl+C.

wc — counting lines, words, and bytes

The wc (word count) command is a simple command that answers quick questions about a file’s content:

wc /var/log/syslog

The output shows three numbers: total lines, total words, and total bytes. Most of the time, you only want the line count:

wc -l /var/log/syslog

This answers questions like “how many lines are in this log?”, “is this configuration file large?”, “how many entries are in /etc/passwd?” (each line = one user).

It seems trivial, but it’s one of the most used commands in scripts and pipelines:

grep -c "ERROR" app.log          # conta ocorrências direto
ps aux | grep nginx | wc -l      # quantos processos nginx estão rodando

diff — comparing files

The diff command compares two files and shows exactly what changed between them:

diff /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Lines beginning with < exist only in the first file. Those beginning with > exist only in the second.

When you back up a file before editing it (which you always should), diff shows exactly what you changed.

A more visual version is diff -u (unified format), which shows differences with context, in the same format that Git uses:

diff -u original.conf modificado.conf

Lines with - were removed, and lines with + were added. Anyone who has used git diff will immediately recognize the format — because it’s literally the same.

grep, sort, and friends

Date and Time

date                        # mostra a data
sudo date -s "..."          # configura a data
date -u                     # mostra o horário UTC
date +%d/%m/%Y              # muda o formato de exibição
date +%d-%m-%y

df — disk space

CommandWhat it does
dfShows free space on each mounted partition in the operating system
df -HHuman-readable format, using base 1000
df -hHuman-readable format, using base 1024
df -mShows everything in megabytes
df -lShows only local filesystems
df -iShows inode usage of the filesystem
df -TShows disk usage including the filesystem type
df -ThHuman-readable format and FS type — the most useful for daily tasks

What is an inode?

An inode is a kind of “internal record” that Linux uses to control files and directories. Each file uses 1 inode.

That’s why df -i matters: it shows if the system still has the capacity to create new files and directories — not just if it has free GBs. You can have 200 GB remaining and still get No space left on device because the inodes ran out. It’s a classic scenario on servers full of small files, like session caches.

Process Management and Execution

ps                  # mostra os processos rodando no terminal atual
ps -a               # todos os processos em execução em outros terminais do meu usuário
ps aux              # todos os processos do sistema, formato completo
ps aux | grep nginx # filtra por um processo específico

The /proc

The /proc is a virtual filesystem. It’s not a regular folder on the disk.

It shows information about the kernel, processes, memory, CPU, network, etc. It’s like a Linux diagnostic panel — each running process has a /proc/<PID> directory with everything about it.

Tools like ps and top don’t have any magic: they just read /proc and format the output.

Wrapping Up

Nothing here is exotic, and that’s precisely the point: these are the commands you type a hundred times a day without thinking — until the day you need a specific flag and can’t remember it.

If I had to choose the five commands that most changed my daily routine from the list above, they would be: tail -f | grep (real-time investigation), less (navigating any documentation), diff -u (before any production change), df -Th (the first command when something breaks), and ls -lha (pure reflex).

I’ll leave this page open as a reference, and I suggest you create your own.

Next notes: permissions (chmod, chown, umask), package management, and systemd.

References

What did you think?