Skip to content

Linux basics

~14 min

In short

Most servers and many development tools run Linux. You do not need to administer a Linux machine for this course. You do need to know where files live, what permission letters mean, how to find and stop a process, how to install a tool, and what an environment variable is. Some outputs below come from macOS, the machine used to check this page. The notes say where Linux differs.

The file system layout

Everything on a Linux system sits under one root folder, /. The Filesystem Hierarchy Standard describes what each top-level folder is for [1]:

Folder What it holds [1]
/bin, /sbin Essential command programs
/etc Host-specific system configuration
/home User home folders (optional in the standard)
/lib Essential shared libraries
/opt Add-on application packages
/tmp Temporary files
/usr User-level programs, libraries, and shared data
/var Variable data such as logs and caches
/dev, /proc, /sys Device files and kernel information (the last two are virtual) [1]

Run ls / to see the top level. On the Mac used here:

$ ls /
Applications
Library
System
Users
Volumes
bin
...
tmp
usr
var

The Mac has /Users where Linux usually has /home. The standard describes Linux, not macOS. On the Mac, /tmp is a link to /private/tmp:

$ ls -ld /tmp /etc
lrwxr-xr-x@ 1 root  wheel  11 Jul 17  2024 /etc -> private/etc
lrwxr-xr-x@ 1 root  wheel  11 Jul 17  2024 /tmp -> private/tmp

The l at the start of each line marks a symbolic link.

Permissions: ls -l and chmod

Every file has three sets of permission bits: for the owner, the group, and everyone else. Each set has r (read, value 4), w (write, value 2), and x (execute, value 1) [2].

$ ls -l hello.sh
-rw-r--r--  1 ankush  wheel  28 Oct 18 00:28 hello.sh

Read the first ten characters as: type, owner, group, others. Here - means a regular file, rw- is owner read and write, and r-- is group and others read only.

A script needs the execute bit to run directly:

$ ./hello.sh
permission denied
$ chmod u+x hello.sh
$ ls -l hello.sh
-rwxr--r--  1 ankush  wheel  28 Oct 18 00:28 hello.sh
$ ./hello.sh
script ran

The error text comes from the shell, so it varies. The shell used here printed permission denied. Bash prints Permission denied.

chmod changes the bits [2]. Two forms:

  • Symbolic: chmod u+x file adds execute for the owner only. g-w removes write from the group. o=r sets others to read only, clearing the rest.
  • Octal: each digit is the sum of r=4, w=2, and x=1 for owner, group, and others. So 755 means owner rwx (7), group r-x (5), others r-x (5). 600 means owner rw-, and nobody else has any access.
$ chmod 600 hello.sh && ls -l hello.sh
-rw-------  1 ankush  wheel  28 Oct 18 00:28 hello.sh
$ chmod 755 hello.sh && ls -l hello.sh
-rwxr-xr-x  1 ankush  wheel  28 Oct 18 00:28 hello.sh

Use 600 for files that hold secrets, and 755 for scripts other people run.

Processes: ps, top, and kill

A process is a running program. Each has a PID, a process ID number [3]. Running ps lists them.

$ sleep 600 &
$ echo "pid=$!"
pid=70051
$ ps -p 70051 -o pid,ppid,stat,command
  PID  PPID STAT COMMAND
70051 70029 SN   sleep 600

ps -ef and ps aux list every process. The aux form adds %CPU and %MEM columns, which show the share of CPU time and memory used [3]. PPID is the parent process ID [3]. For a live view that refreshes, run top. On macOS, top -l 1 prints one sample and exits. On Linux, top on its own starts the live view, and man top lists its options.

kill sends a signal to a process. With no option, it sends TERM, which lets the program clean up. kill -9 sends KILL, which cannot be caught, so use it only when TERM fails [4].

$ kill 70051
$ ps -p 70051 -o pid,stat,command
  PID STAT COMMAND
$ sleep 300 & P2=$!; kill -9 $P2; wait $P2 2>/dev/null; echo "status=$?"
status=137

The empty ps output means the process is gone. The status 137 is what the shell reported for that process after kill -9.

Package managers

A package manager downloads, installs, and updates software. Each operating system has one or more:

  • Debian and Ubuntu (apt): apt update downloads the package lists. apt install <package> installs one or more packages [5]. Run sudo apt update before installing, and use sudo only when a command needs administrator rights.
  • macOS (Homebrew): brew install <formula> installs a formula or cask [6].
$ brew --version | head -1
Homebrew 7.0.9
$ brew --prefix
/usr/local
$ which git
/usr/bin/git

The commands that change the system were not run on this machine. The version check and the prefix are read-only.

On Windows, WSL installs Ubuntu by default, so apt works inside it [7].

Environment variables

An environment variable is a named value that a program inherits from its parent [8]. The PATH variable lists the folders the shell searches for commands.

$ export GREETING=hello
$ sh -c 'echo $GREETING'
hello
$ NOT_EXPORTED=x
$ sh -c 'echo [$NOT_EXPORTED]'
[]

export adds a variable to the environment, so child programs see it [8]. A plain assignment does not. Check your PATH:

$ echo $PATH | tr ":" "\n" | head -3
/Users/ankush/.bun/bin
/Users/ankush/.local/bin
/Users/ankush/.local/bin

If a command is "not found" after you installed it, check whether its folder is in PATH, using which name.

Try this

  1. Run ls / and identify three folders from the table. Then run ls -ld /tmp and explain the output in one sentence.
  2. Create a script in /tmp, remove its execute bit with chmod u-x, run it and read the error. Then add the bit back with chmod u+x.
  3. Start sleep 500 &, find its PID with ps, stop it with kill, and confirm with ps -p.
  4. Run export MYNAME=yourname, then open a new terminal and run echo $MYNAME. The value is gone, because the variable lived only in the first shell.

Sources

  • [1] Linux Foundation, Filesystem Hierarchy Standard 3.0. https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
  • [2] chmod(1), Linux man-pages. https://man7.org/linux/man-pages/man1/chmod.1.html
  • [3] ps(1), Linux man-pages. https://man7.org/linux/man-pages/man1/ps.1.html
  • [4] kill(1), Linux man-pages. https://man7.org/linux/man-pages/man1/kill.1.html
  • [5] apt(8), Debian manual pages. https://manpages.debian.org/bookworm/apt/apt.8.en.html
  • [6] Homebrew documentation, manpage. https://docs.brew.sh/Manpage
  • [7] Microsoft Learn, "Install WSL". https://learn.microsoft.com/en-us/windows/wsl/install
  • [8] GNU Bash manual, "Environment". https://www.gnu.org/software/bash/manual/html_node/Environment.html