Jhonatan Pinheiro
Loading page...
Jhonatan Pinheiro
Loading page...
Jhonatan Pinheiro
Loading page...
Navigation, files, permissions, users, processes, packages, disk, network, archiving and search: 200 commands with copy-ready examples.
Every server you will administer, every container you will debug and a good part of the tools you use run on Linux. Learning the terminal stops being optional very quickly.
These 200 commands are the foundation: navigating, reading, editing, granting permissions, killing a process, installing a package, checking the disk, testing the network, archiving and searching. The examples use Debian/Ubuntu as the reference, with the RHEL/Fedora variation noted where it differs.
A tip that saves hours:
Tabcompletes names,Ctrl+Rsearches the history andman command(orcommand --help) answers before Google does.
Where you are, what is here and how to move things around.
Shows the current directory in full.
pwdThe most used command in the terminal.
lsPermissions, owner, size and date of each item.
ls -lFiles starting with a dot only show up with -a.
ls -la-h swaps bytes for KB, MB and GB.
ls -lhMost recent first — great for finding what has just changed.
ls -lt
ls -ltr # oldest firstNavigates to the given path.
cd /var/logHome, previous, up. The three you use the most.
cd ~ # the user's home
cd - # the previous directory
cd .. # one level upStarting with / is absolute; without it, it starts from where you are.
cd /etc/nginx # absolute
cd nginx/conf.d # relativeCreates a folder.
mkdir projetosCreates any missing parents and does not complain if it already exists.
mkdir -p projetos/api/srcCreates the file or updates its modification date.
touch notas.txtCopies a file, keeping the original.
cp origem.txt destino.txt-r is mandatory for folders.
cp -r projetos/ backup-projetos/-a keeps permissions, owner and dates. The right way to copy a backup.
cp -a /var/www/ /backup/www/The same command does both.
mv antigo.txt novo.txt
mv relatorio.pdf ~/Documentos/There is no recycle bin. What goes from here is gone.
rm arquivo.txtRemoves recursively.
rm -r pasta-antiga/Asks about each file. The habit is worth having on a server.
rm -i *.logOne extra space wipes the system. Check the path twice before Enter.
rm -rf /caminho/certo # check first
# rm -rf / caminho <- the space here wipes everythingA shortcut pointing at another path.
ln -s /var/www/site /home/user/siteVisualises the structure; -L limits the depth.
tree -L 2They separate the file name from the path. Heavily used in scripts.
basename /var/log/syslog # syslog
dirname /var/log/syslog # /var/logResolves links and relative paths down to the absolute path.
realpath ../projetoThe shell expands the pattern before the command runs.
ls *.log # ends in .log
ls arquivo?.txt # any single character
ls dados[1-3].csv # a rangeReading a big file without freezing the terminal and editing without leaving SSH.
Dumps the whole content. Careful with a large file.
cat /etc/hostnameMakes it easier to talk about line X of the file.
cat -n script.shThe right way to open a large file. q exits, / searches, G goes to the end.
less /var/log/syslogThe first 10 lines by default.
head arquivo.csv
head -n 50 arquivo.csvThe last lines — where the recent error usually is.
tail -n 100 /var/log/nginx/error.logFollows the file as it grows. The on-call command.
tail -f /var/log/nginx/access.logLike -f, but it survives log rotation.
tail -F /var/log/app.logLines, words and bytes.
wc -l acesso.log # lines
wc -w texto.txt # words
wc -c arquivo.bin # bytesFor when you just need to edit and get out. Ctrl+O saves, Ctrl+X exits.
nano /etc/hostsIt is on any server. i inserts, Esc leaves the mode, :wq saves and closes, :q! exits without saving.
vim /etc/nginx/nginx.confSorts the lines; -n numeric, -r reverse.
sort nomes.txt
sort -nr valores.txtIt only works on adjacent lines — combine it with sort.
sort acessos.log | uniq
sort acessos.log | uniq -c | sort -nr # a rankingExtracts fields by delimiter or position.
cut -d: -f1 /etc/passwd # users
cut -c1-10 arquivo.txt # the first 10 charactersConverts or removes characters from the stream.
echo "texto" | tr 'a-z' 'A-Z'
tr -d '\r' < arquivo-windows.txt > arquivo-unix.txtShows what changed between two files.
diff config-antigo.conf config-novo.conf
diff -u a.txt b.txt # unified format, as in gitLike cat -n, with more formatting options.
nl arquivo.txtBreaks a large file into pieces.
split -l 1000 grande.csv parte_They verify the integrity of a download.
sha256sum imagem.iso
sha256sum -c checksums.txtFinds out the real type, ignoring the extension.
file documento.pdf
file *Size, permissions, owner and the file's three dates.
stat arquivo.txtThe Unix security model: who can read, write and execute what.
-rwxr-xr--: type, owner, group and others. r=4, w=2, x=1.
ls -l arquivo.sh
# -rwxr-xr-- owner: rwx (7) | group: r-x (5) | others: r-- (4)The most common form: three digits, one per class.
chmod 644 arquivo.txt # owner reads/writes, the rest read
chmod 755 script.sh # everyone executes, only the owner writes
chmod 600 ~/.ssh/id_ed25519 # only the owner, and nothing elseAdds or removes a permission without recalculating everything.
chmod +x script.sh
chmod u+w,go-w arquivo.txt
chmod a-x binarioApplies to the whole tree. Take care not to hand out 777 on the server.
chmod -R 755 /var/www/siteA directory needs x to be traversed; a file does not.
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;Only root can hand a file to another user.
sudo chown www-data arquivo.html
sudo chown www-data:www-data -R /var/wwwChanges only the owning group.
sudo chgrp desenvolvedores projeto/Defines what is subtracted from the permissions of new files.
umask # 0022 is the default
umask 0077 # new files for the owner onlyRuns with the file's owner, not with whoever called it. That is why passwd works.
ls -l /usr/bin/passwd # -rwsr-xr-x
sudo chmod u+s programaOn a directory, it makes every file created inherit the folder's group.
sudo chmod g+s /projetos/compartilhadoIn a shared folder, only the owner deletes their own file. It is what protects /tmp.
ls -ld /tmp # drwxrwxrwt
sudo chmod +t /pasta-compartilhadaIt goes beyond owner/group/others: permissions per specific user.
setfacl -m u:jhonatan:rw arquivo.txt
getfacl arquivo.txt+i makes the file immutable — not even root can change it without removing the attribute.
sudo chattr +i /etc/resolv.conf
lsattr /etc/resolv.conf
sudo chattr -i /etc/resolv.confIt asks for your password and records in the log who did what.
sudo apt updateThey open a root shell. Prefer a targeted sudo command.
sudo -i
su - outro-usuarioThe most satisfying shortcut in the terminal.
sudo !!Lists your user's sudo permissions.
sudo -lFull permission for any user on the system. There is nearly always an owner/group combination that solves it.
# instead of: chmod -R 777 /var/www
sudo chown -R www-data:www-data /var/www
sudo chmod -R 755 /var/wwwWho exists on the machine and what each one can do.
Who you are and which groups you belong to.
whoami
id
id jhonatanWho is connected right now; w also shows what they are running.
who
wThe last accesses to the machine — the first stop in an audit.
last
last -n 20adduser (Debian) is interactive and creates a home; useradd is the raw command.
sudo adduser maria
sudo useradd -m -s /bin/bash mariaChanges your own password or another user's (as root).
passwd
sudo passwd mariaAdds to groups, changes the shell, moves the home.
sudo usermod -aG sudo maria # -a is mandatory so as NOT to remove the other groups
sudo usermod -s /bin/zsh maria-r also deletes the home folder.
sudo userdel maria
sudo userdel -r mariaCreates a group and lists a user's groups.
sudo groupadd desenvolvedores
groups mariaWhere users and groups are recorded (the password lives in /etc/shadow).
cat /etc/passwd | cut -d: -f1,3,7
cat /etc/groupPrevents login without deleting the user.
sudo usermod -L maria # locks
sudo usermod -U maria # unlocksA policy of periodic changes.
sudo chage -l maria
sudo chage -M 90 maria # expires in 90 daysNo shell and no login: an application does not need interactive access.
sudo useradd -r -s /usr/sbin/nologin appWhat is running, how much it consumes and how to stop it.
The full process listing, with CPU and memory.
ps auxCombined with grep, it finds the specific process.
ps aux | grep nginxShows the hierarchy of parents and children.
ps auxf
pstree -pIt refreshes on its own. q exits, k kills, M sorts by memory.
topColourful, with scrolling and mouse support. Worth installing on every server.
htopSends SIGTERM (15): it asks the process to shut down properly.
kill 12345SIGKILL cannot be ignored, but the process saves nothing. Use it last.
kill -9 12345They kill by name, with no need for the PID.
pkill nginx
killall firefoxLooks for a process by name.
pgrep -a nginx& releases the process; jobs lists them; fg brings one back.
./script-longo.sh &
jobs
fg %1The process keeps going after you close the SSH session.
nohup ./backup.sh > backup.log 2>&1 &Suspends the foreground process and resumes it in the background.
# Ctrl+Z suspends
bg # continues in the background
fg # brings it backRuns at a lower priority, so as not to disturb the rest.
nice -n 19 ./tarefa-pesada.sh
renice -n 10 -p 12345Kills the command if it runs over time.
timeout 30s ./script.shRuns it every N seconds and shows the updated result.
watch -n 2 'df -h /'Finds out who is using a file or a port.
lsof /var/log/app.log
sudo lsof -i :8080How long the machine has been up and the load over 1, 5 and 15 minutes.
uptimeMemory used, free and cached. available is the number that matters.
free -hInstalling, updating and removing software on your distribution.
Updates the package list. It does not install anything.
sudo apt updateUpdates the installed packages.
sudo apt upgrade
sudo apt full-upgradeInstalls one or several packages.
sudo apt install -y htop curl gitremove takes the program away; purge takes the configuration files with it.
sudo apt remove nginx
sudo apt purge nginxRemoves dependencies that have been left orphaned.
sudo apt autoremoveSearches for and details a package before installing it.
apt search postgresql
apt show postgresql-16Everything installed on the machine.
apt list --installed | lessThe equivalents of apt in the Red Hat world.
sudo dnf install htop
sudo dnf update
sudo dnf remove htopArch Linux's package manager.
sudo pacman -S htop
sudo pacman -SyuThey install a local package, without resolving dependencies automatically.
sudo dpkg -i pacote.deb
sudo apt install -f # fixes the dependencies
sudo rpm -i pacote.rpmUniversal formats, with the application sandboxed.
sudo snap install code --classic
flatpak install flathub org.gimp.GIMPWhere the binary that will run actually is.
which python3
whereis nginxTells you whether it is a binary, an alias, a function or a shell builtin.
type ls
type cdAdds a third-party source with its signing key.
curl -fsSL https://exemplo.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/exemplo.gpg
echo "deb [signed-by=/usr/share/keyrings/exemplo.gpg] https://exemplo.com/apt stable main" | sudo tee /etc/apt/sources.list.d/exemplo.listFrees space on a tight server.
sudo apt clean
sudo apt autocleanThe most common question on a server: who filled the disk?
An overview of the disk. The first command when something stops writing.
df -hA disk can fill up with files even with free space. Millions of tiny files exhaust the inodes.
df -iHow much each folder takes up.
du -sh /var/logThe recipe for finding the space villain.
du -h --max-depth=1 /var | sort -hr | head -20Interactive: you browse and delete right there. Worth installing.
ncdu /varFinds the large files in one go.
find / -type f -size +500M -exec ls -lh {} \; 2>/dev/nullA tree of block devices.
lsblk
lsblk -f # with the filesystem and UUIDConnects a device to a directory.
sudo mount /dev/sdb1 /mnt/dados
mount | column -tIt fails if something is using it; lsof reveals who.
sudo umount /mnt/dados
sudo lsof +D /mnt/dadosMounts applied at boot. A mistake here can stop the machine from coming up.
cat /etc/fstab
sudo mount -a # tests fstab without rebootingLogs are usually the first suspect.
sudo du -sh /var/log/*
sudo journalctl --disk-usageA process still holding the file open keeps the space until it is restarted.
sudo lsof | grep deletedSpace that is easy to recover in an emergency.
sudo apt clean
sudo journalctl --vacuum-time=7dGenerates a file of a set size to test the disk.
dd if=/dev/zero of=teste.img bs=1M count=100
fallocate -l 1G teste.imgA quick I/O test of the disk.
dd if=/dev/zero of=teste bs=1M count=1024 oflag=directFinding out the IP, testing the connection and seeing what is listening.
The modern replacement for ifconfig.
ip a
ip -br a # the short versionShows the default gateway and the configured routes.
ip rThe first connectivity test.
ping -c 4 google.comThe Swiss army knife of the web on the command line.
curl https://api.exemplo.com/status
curl -I https://exemplo.com # the headers only
curl -s -o /dev/null -w "%{http_code}\n" https://exemplo.comTests an API without leaving the terminal.
curl -X POST https://api.exemplo.com/itens \
-H "Content-Type: application/json" \
-d '{"nome":"teste"}'A resilient download, with resume.
wget https://exemplo.com/arquivo.tar.gz
wget -c https://exemplo.com/grande.iso # continues an interrupted downloadThe replacement for netstat. It shows who is listening.
ss -tuln
sudo ss -tulpn # with the process owning the portThe answer to "address already in use".
sudo ss -tulpn | grep :8080
sudo lsof -i :8080Resolves a name and shows the full answer.
dig exemplo.com
dig +short exemplo.com
dig @8.8.8.8 exemplo.comSimpler DNS queries.
host exemplo.com
nslookup exemplo.comShows the path to the destination and where the latency shows up.
traceroute exemplo.com
mtr exemplo.com # a continuous tracerouteThe address your machine appears with on the internet.
curl -s ifconfig.me
curl -s https://api.ipify.orgThe machine's name on the network.
hostname
hostname -I # IPs
sudo hostnamectl set-hostname servidor01Local resolution, before DNS. Great for testing before pointing the domain.
cat /etc/hosts
# 192.168.0.10 meu-site.localChecks whether the port is open on the other side.
nc -zv exemplo.com 443
timeout 3 bash -c "</dev/tcp/exemplo.com/443" && echo abertaPacking, compressing and moving files between machines.
creates, z compresses with gzip, verbose, file.
tar -czvf backup.tar.gz pasta/x extracts. -C chooses the destination.
tar -xzvf backup.tar.gz
tar -xzvf backup.tar.gz -C /destinoCheck the contents before unpacking.
tar -tzvf backup.tar.gzA backup without node_modules or .git.
tar -czvf app.tar.gz --exclude=node_modules --exclude=.git app/xz and zstd compress better; zstd is much faster.
tar -cJvf backup.tar.xz pasta/
tar --zstd -cvf backup.tar.zst pasta/Compresses a single file (replacing the original).
gzip arquivo.log
gunzip arquivo.log.gz
zcat arquivo.log.gz | less # reads it without decompressingA universal format, compatible with Windows.
zip -r pasta.zip pasta/
unzip pasta.zip -d destino/Transfers between machines using the SSH connection.
scp arquivo.txt usuario@servidor:/caminho/
scp -r pasta/ usuario@servidor:/caminho/
scp usuario@servidor:/caminho/arquivo.txt .Copies only the difference and resumes where it left off. Better than scp for volume.
rsync -avz pasta/ usuario@servidor:/destino/Mirrors the destination, deleting whatever no longer exists at the source.
rsync -avz --delete --exclude=node_modules ./site/ usuario@servidor:/var/www/site/--dry-run shows what it would do, without doing it. Always use it before --delete.
rsync -avzn --delete origem/ destino/Follows the transfer of a large file.
rsync -avz --progress grande.iso usuario@servidor:/dados/An interactive transfer session over SSH.
sftp usuario@servidor
# get arquivo.txt / put local.txt / ls / byePacks, sends and unpacks on the other side, with no intermediate file.
tar -czf - pasta/ | ssh usuario@servidor "tar -xzf - -C /destino"A simple pattern that avoids overwriting a backup.
tar -czf backup-$(date +%F-%H%M).tar.gz /var/wwwfind searches by attributes; grep searches inside the content.
The most common search.
find /var -name "*.log"
find . -iname "readme*" # without distinguishing caseFile (f), directory (d) or link (l).
find /etc -type f -name "*.conf"
find /var -type d -name "cache"+ larger, - smaller.
find / -type f -size +100M
find . -type f -size -1kModified in the last days or minutes.
find /var/log -mtime -1 # the last 24 h
find /tmp -mmin -30 # the last 30 minAuditing: files belonging to a user or with a dangerous permission.
find /home -user maria
find / -perm -4000 -type f 2>/dev/null # SUID binaries-exec runs a command on each result; -delete removes it.
find /tmp -name "*.tmp" -mtime +7 -delete
find . -name "*.sh" -exec chmod +x {} \;Faster than -exec on many files. -print0/-0 handles names with spaces.
find . -name "*.log" -print0 | xargs -0 rmAvoids sweeping the whole tree.
find /var -maxdepth 2 -name "*.conf"It queries an index; far faster, but out of date until the next updatedb.
locate nginx.conf
sudo updatedbLooks for the pattern inside the files.
grep "erro" /var/log/syslogSweeps the entire directory tree.
grep -r "TODO" src/-i ignores the case.
grep -i "error" app.log-n says where it is.
grep -n "senha" config.py-v shows what does not match — great for filtering out noise.
grep -v "DEBUG" app.logLines before and after the hit.
grep -B 3 -A 5 "Exception" app.log
grep -C 3 "Exception" app.log-c counts the occurrences; -l lists only the files.
grep -c "404" access.log
grep -rl "senha" /etc-w stops test matching inside testing.
grep -w "test" arquivo.txt-E enables |, + and ? without escaping.
grep -E "erro|falha|timeout" app.logPrefixes each result with the file name.
grep "database" /etc/*.confFar faster and it already respects .gitignore.
rg "getThemeSelection"
rg -t ts "useState"Shortcuts, history and help — what makes you type less.
Completes a command, a path and a file name. Two presses list the options.
cd /var/lo<Tab> # becomes /var/log/Every command you have run.
history
history | grep docker!! repeats the last one; !123 runs number 123.
!!
!123
!docker # the last one starting with dockerThe shortcut that saves the most typing. Keep pressing it to go further back.
# Ctrl+R and start typing part of the commandMoving and deleting without the arrow keys.
# Ctrl+A start | Ctrl+E end
# Ctrl+U deletes to the start | Ctrl+K to the end
# Ctrl+W deletes the previous word | Ctrl+L clears the screenInterrupts the current command; ends the input/session.
# Ctrl+C cancels
# Ctrl+D sends EOF (exits the shell)A long command becomes a short word.
alias ll='ls -lah'
alias gs='git status'
alias ..='cd ..'Put it in your shell's profile file.
echo "alias ll='ls -lah'" >> ~/.bashrc
source ~/.bashrcViewing, creating and exporting them to child processes.
echo $HOME
export API_URL="https://api.exemplo.com"
printenv | sortWhere the shell looks for executables.
echo $PATH
export PATH="$HOME/bin:$PATH"The official documentation for each command. / searches, q exits.
man tar
man 5 crontab # section 5: file formatsA quick summary, without opening the manual.
tar --help | lessA condensed manual, with the common uses only. Worth installing.
tldr tar
tldr findSearches the manual by what the command does.
apropos compressClears the screen; reset fixes a terminal messed up by binary output.
clear
reset; always, && if it succeeded, || if it failed.
cd /tmp; ls
mkdir dados && cd dados
ping -c1 host || echo "sem resposta"> overwrites, >> appends, 2> is the error stream.
ls > lista.txt
echo "linha" >> log.txt
comando > saida.txt 2> erros.txt
comando > tudo.txt 2>&1Knowing what you are standing on before touching anything.
Shows and formats the date. Heavily used in file names.
date
date +"%Y-%m-%d %H:%M:%S"
date +%s # Unix timestampThe calendar for the month or the year.
cal
cal 2026Configures the time zone and NTP synchronisation.
timedatectl
sudo timedatectl set-timezone America/Sao_PauloWhich kernel and which architecture the machine uses.
uname -a
uname -r # just the kernel versionThe name and version of the system.
cat /etc/os-release
lsb_release -aModel, cores and frequency.
lscpu
nproc # just the number of coresAn inventory of what the machine has.
free -h
sudo lshw -short
sudo dmidecode -t memoryNetwork card, GPU, connected devices.
lspci
lsusbHow long it has been up and the history of restarts.
uptime -p
last reboot | headAlways warn whoever is connected first.
sudo shutdown -h now
sudo shutdown -r +5 "Reinício em 5 minutos"
sudo shutdown -c # cancels