Sign in Get started
Solutions
ComplianceDigital ForensicsAccount SecurityWebsite SecurityWeb OptimizationSEO / GEOBusiness IntelligenceUI / UXStartupsDigital TransformationWhite LabelAI Code AuditAI / MLConsulting & AdvisoryBusiness Strategy
Products
Web HostingVPS HostingSSL CertificatesSiteLock SecurityWebsite BackupEmail Spam FilterOX App Suite360 MonitoringWeebly BuilderSite BuilderSEO (Marketgoo)Account SecurityDomainsAll Products
More
NetworkSecurity AboutCareersContactRoadmapLegal
Guide

Linux command line essentials for developers

Servers, containers and most deploy tools run Linux, and you work with them through a terminal. A short list of commands covers most of that work. This guide covers moving around, searching files with grep, installing software on the main distributions, file permissions, and the security layers SELinux and AppArmor.

No Linux machine at hand? On Windows, WSL 2 gives you a real Linux terminal. On a Mac, the Terminal app accepts most of the commands below.

Moving around and handling files

pwd                  # where am I
ls -la               # list everything, with details
cd /var/log          # go to a folder
cd ~                 # home folder
cd -                 # back to the previous folder
mkdir -p app/static  # create folders, including parents
cp -r src backup     # copy a folder
mv old.txt new.txt   # move or rename
rm file.txt          # delete, with no recycle bin
less app.log         # read a long file; q to quit
tail -f app.log      # follow a log as it grows

Press Tab to complete file and folder names, and the up arrow to repeat earlier commands. man ls, or ls --help, shows every option of a command.

Be careful with rm -r. There is no undo, and a stray space in a path can delete the wrong folder. Run ls on the same path first.

Searching with grep

grep prints the lines that match a pattern. It is the quickest way to find a setting, a function call or an error in a log. These are the flags worth learning:

grep -i "error" app.log              # ignore case
grep -n "TODO" *.py                  # show line numbers
grep -rn "API_URL" src/              # search a folder
grep -rl "oldName" .                 # only list matching files
grep -v "DEBUG" app.log              # lines that do NOT match
grep -w "id" models.py               # whole word only
grep -c "404" access.log             # count matching lines
grep -E "fail(ed|ure)" app.log       # extended regular expressions
grep -C 3 "Traceback" app.log        # 3 lines of context around matches
grep -rn --include="*.js" "fetch(" . # only some file types

grep also reads the output of other commands through a pipe, written |:

ps aux | grep nginx
journalctl -u nginx --since today | grep -i error

In a large code base, ripgrep (rg) does the same job faster and skips files listed in .gitignore. Most distributions package it.

Installing software

Each distribution family has its own package manager. It installs software from the distribution's repositories, resolves dependencies and handles updates. Use it before downloading programs from websites.

# Debian, Ubuntu
sudo apt update && sudo apt upgrade
sudo apt install git curl
apt search imagemagick
sudo apt remove imagemagick

# Fedora, RHEL, AlmaLinux, Rocky
sudo dnf upgrade
sudo dnf install git curl
dnf search imagemagick

# Arch
sudo pacman -Syu
sudo pacman -S git curl
pacman -Ss imagemagick

Fedora 41 and later ship dnf5 as dnf. The commands are the same as in older dnf, but some output looks different. On Arch, always upgrade the whole system with -Syu before installing; partial upgrades are not supported.

Snap and Flatpak are universal formats. They bundle an app with its dependencies, so the same package runs on many distributions. Snap is built into Ubuntu. Flatpak apps usually come from Flathub, and Fedora includes Flatpak by default. They suit desktop apps; for server software, the distribution's packages are the usual choice.

sudo snap install code --classic
flatpak install flathub org.gimp.GIMP

Permissions

Every file has an owner, a group, and three sets of permissions: for the owner, for the group, and for everyone else. ls -l shows them as a string such as -rwxr-xr-x. r is read, w is write, and x is execute, which for a folder means you may enter it.

Reading a permission stringOwner: rwx = 7read 4 + write 2 + run 1The user who owns the fileGroup: r-x = 5read 4 + run 1Members of the file groupOthers: r-x = 5read 4 + run 1Every other userOwner: rwx = 7read 4 + write 2 + run 1The user who owns the fileGroup: r-x = 5read 4 + run 1Members of the file groupOthers: r-x = 5read 4 + run 1Every other user
The permissions -rwxr-xr-x read as 755: three digits for owner, group and others.
ls -l deploy.sh
chmod +x deploy.sh                 # let it run
chmod 640 .env                     # owner read/write, group read, others nothing
sudo chown www-data:www-data uploads/
sudo chown -R you:you ~/projects   # -R for a whole folder

Common numbers: 644 for normal files, 755 for scripts and folders, 600 or 640 for files with secrets. Avoid chmod 777. It lets every user and every process on the machine change the file, and it is a frequent cause of compromised web servers. Our security checklist covers the rest of server hardening.

sudo runs a single command as the administrator, root. Use it for that command only, and avoid working in a root shell.

SELinux and AppArmor

Normal permissions ask who you are. SELinux and AppArmor add a second check: what a given program is allowed to do. If a web server is compromised, the attacker is limited to the files and actions its policy allows, even when it runs as root. This is called mandatory access control.

  • SELinux is on by default in Fedora, RHEL, AlmaLinux and Rocky Linux. Every file and process carries a label, and the policy says which labels may access which. Modes are Enforcing (blocks and logs), Permissive (logs only) and Disabled.
  • AppArmor is on by default in Ubuntu and Debian. It uses per-program profiles based on file paths. Profiles run in enforce or complain mode.
# SELinux (Fedora, RHEL and similar)
getenforce
sestatus
sudo ausearch -m avc -ts recent
ls -Z /var/www/html
sudo restorecon -Rv /var/www/html

# AppArmor (Ubuntu, Debian)
sudo aa-status
sudo journalctl -k | grep -i apparmor

A typical SELinux surprise: you copy a site into /var/www/html, the permissions look right, and the web server still gets "permission denied". The files kept the label of the folder you copied them from. restorecon fixes the labels. If your app needs to reach the network or a database, the right fix is usually an SELinux boolean, for example sudo setsebool -P httpd_can_network_connect on. Keep SELinux on. The Fedora SELinux guide and Ubuntu's AppArmor documentation go further.

Common questions

Which distribution should I learn on?
Ubuntu or Debian is a good start: it has the most tutorials and is common on servers. The commands in this guide work on the others with their own package manager.
What does sudo !! do?
It repeats your last command with sudo. Useful when a command failed only because it needed administrator rights.
Should I disable SELinux when something breaks?
Switch to permissive mode with sudo setenforce 0 to confirm SELinux is the cause, fix the label or boolean, then switch back with sudo setenforce 1.
How do I find which package provides a command?
On Fedora, run dnf provides followed by the command. On Ubuntu, install apt-file, run apt-file update, then apt-file search with the command name.

Working on servers for clients? Getting paid on Internetivo explains how professionals find paid tasks and get paid for accepted work. For a full deploy walk-through, see deploying a React or Django app.