5. processes and services - mishraxharshit/harshitxmishra.github.io GitHub Wiki
Previous: Phase 4 — Users and Permissions | Next: Phase 6 — Networking
When the kernel runs a program, it creates a process. A process is the running instance of a program. A single program can have many processes running simultaneously (for example, multiple browser tabs as separate processes).
Every process has:
- A unique PID (Process ID)
- A PPID (Parent Process ID) — the process that started it
- An owner (UID) — the user it runs as
- A state: running, sleeping, stopped, zombie
- File descriptors: open files, sockets, pipes
# ps: snapshot of current processes
ps # processes in current terminal session
ps aux # all processes, all users, with details
# a = all users, u = user-friendly format, x = include processes without terminal
Understanding ps aux output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 167916 6480 ? Ss Jan10 0:03 /sbin/init
alice 1823 2.1 1.5 456320 30240 pts/0 S+ 10:22 0:01 python3 server.py
VSZ = virtual memory size, RSS = resident (actual RAM used)
STAT: S=sleeping, R=running, Z=zombie, T=stopped, I=idle
The + in S+ means it is in the foreground of a terminal
Filter for a specific process
ps aux | grep nginx
ps -p 1823 # show process with specific PID
top: live, updating view
top
Keys inside top:
q quit
k kill a process (enter PID)
u filter by user
M sort by memory
P sort by CPU
1 show per-CPU statistics
htop: improved version of top (install if not present)
sudo apt install htop
htop
Signals are notifications sent to processes. A process can catch and handle most signals, but SIGKILL and SIGSTOP cannot be caught.
| Signal | Number | Meaning |
|---|---|---|
| SIGTERM | 15 | Polite request to terminate (process can clean up) |
| SIGKILL | 9 | Force kill, cannot be caught or ignored |
| SIGHUP | 1 | Reload configuration (many daemons respond to this) |
| SIGINT | 2 | Interrupt (same as Ctrl+C in terminal) |
| SIGSTOP | 19 | Pause the process |
| SIGCONT | 18 | Resume a paused process |
# Send a signal by PID
kill 1823 # SIGTERM by default (polite)
kill -9 1823 # SIGKILL (force)
kill -HUP 1823 # SIGHUP (reload config)
# Kill by name (more convenient)
pkill nginx # SIGTERM to all nginx processes
pkill -9 firefox # force kill firefox
# Kill all processes of a user
pkill -u baduser
# Send SIGHUP to nginx to reload config without restart
sudo pkill -HUP nginx
# Start a process in the background
python3 server.py &
# Output: [1] 2847 (job number and PID)
List background jobs in current shell
jobs
[1]+ Running python3 server.py &
Bring a background job to foreground
fg # bring most recent job to foreground
fg %1 # bring job number 1 to foreground
Send current foreground process to background
First: Ctrl+Z (suspends it)
Then:
bg # resume it in background
bg %1 # resume job 1 in background
nohup: run a command that survives terminal close
nohup python3 server.py > server.log 2>&1 &
Output goes to server.log, process continues if you log out
Modern Linux systems use systemd as PID 1. It starts all services on boot and manages them throughout the system's life.
# Service management
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # reload config without full restart
Enable/disable on boot
sudo systemctl enable nginx # start on boot
sudo systemctl disable nginx # do not start on boot
sudo systemctl enable --now nginx # enable AND start right now
Check status
systemctl status nginx
Output looks like this:
nginx.service - A high performance web server
Loaded: loaded (/lib/systemd/system/nginx.conf; enabled)
Active: active (running) since Mon 2024-01-15 10:22:00 UTC
Process: 1823 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 1824 (nginx)
Tasks: 2 (limit: 4915)
Memory: 6.2M
CPU: 42ms
CGroup: /system.slice/nginx.service
├─1824 nginx: master process /usr/sbin/nginx
└─1825 nginx: worker process
List all services
systemctl list-units --type=service
systemctl list-units --type=service --state=failed
View service logs
journalctl -u nginx # all logs for nginx
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -f # follow live logs
journalctl -b # all logs since last boot
journalctl -p err # only error and above
Writing a simple systemd service:
# Create /etc/systemd/system/myapp.service
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Python Application
After=network.target
[Service]
Type=simple
User=alice
WorkingDirectory=/home/alice/myapp
ExecStart=/usr/bin/python3 /home/alice/myapp/server.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
# Reload systemd to pick up new unit file, then start
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
cron runs commands at scheduled times. The schedule is defined in a crontab file.
# Edit your crontab
crontab -e
List your crontab
crontab -l
Edit another user's crontab (as root)
sudo crontab -e -u alice
Crontab format — five time fields followed by the command:
# MIN HOUR DAY_OF_MONTH MONTH DAY_OF_WEEK COMMAND
# 0-59 0-23 1-31 1-12 0-7 (0,7=Sun)
Run every day at 2:30am
30 2 * * * /usr/local/bin/backup.sh
Run every Monday at 8am
0 8 * * 1 /usr/local/bin/weekly_report.sh
Run every 15 minutes
*/15 * * * * /usr/local/bin/check_status.sh
Run at midnight on the 1st of every month
0 0 1 * * /usr/local/bin/monthly_cleanup.sh
Redirect cron output to a log file
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Exercise 1: Run ps aux --sort=-%cpu | head -15. Identify the top three processes by CPU. What do they do?
Exercise 2: Start sleep 300 & to create a background job. Use jobs to see it. Use fg to bring it foreground. Use Ctrl+Z to suspend it. Use bg to resume in background. Use kill %1 to terminate it.
Exercise 3: Check the status of the ssh service with systemctl status ssh. Note whether it is enabled on boot.
Exercise 4: Write a crontab entry that runs the command date >> /tmp/datelog.txt every minute. Wait 3 minutes, then check /tmp/datelog.txt. Then remove the crontab entry.
Previous: Phase 4 — Users and Permissions | Next: Phase 6 — Networking
# Phase 5 — Processes and ServicesPrevious: [Phase 4 — Users and Permissions](Phase-4-Users-and-Permissions) | Next: [Phase 6 — Networking](Phase-6-Networking)
When the kernel runs a program, it creates a process. A process is the running instance of a program. A single program can have many processes running simultaneously (for example, multiple browser tabs as separate processes).
Every process has:
- A unique PID (Process ID)
- A PPID (Parent Process ID) — the process that started it
- An owner (UID) — the user it runs as
- A state: running, sleeping, stopped, zombie
- File descriptors: open files, sockets, pipes
# ps: snapshot of current processes
ps # processes in current terminal session
ps aux # all processes, all users, with details
# a = all users, u = user-friendly format, x = include processes without terminal
# Understanding ps aux output:
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 1 0.0 0.3 167916 6480 ? Ss Jan10 0:03 /sbin/init
# alice 1823 2.1 1.5 456320 30240 pts/0 S+ 10:22 0:01 python3 server.py
# VSZ = virtual memory size, RSS = resident (actual RAM used)
# STAT: S=sleeping, R=running, Z=zombie, T=stopped, I=idle
# The + in S+ means it is in the foreground of a terminal
# Filter for a specific process
ps aux | grep nginx
ps -p 1823 # show process with specific PID
# top: live, updating view
top
# Keys inside top:
# q quit
# k kill a process (enter PID)
# u filter by user
# M sort by memory
# P sort by CPU
# 1 show per-CPU statistics
# htop: improved version of top (install if not present)
sudo apt install htop
htopSignals are notifications sent to processes. A process can catch and handle most signals, but SIGKILL and SIGSTOP cannot be caught.
| Signal | Number | Meaning |
|---|---|---|
| SIGTERM | 15 | Polite request to terminate (process can clean up) |
| SIGKILL | 9 | Force kill, cannot be caught or ignored |
| SIGHUP | 1 | Reload configuration (many daemons respond to this) |
| SIGINT | 2 | Interrupt (same as Ctrl+C in terminal) |
| SIGSTOP | 19 | Pause the process |
| SIGCONT | 18 | Resume a paused process |
# Send a signal by PID
kill 1823 # SIGTERM by default (polite)
kill -9 1823 # SIGKILL (force)
kill -HUP 1823 # SIGHUP (reload config)
# Kill by name (more convenient)
pkill nginx # SIGTERM to all nginx processes
pkill -9 firefox # force kill firefox
# Kill all processes of a user
pkill -u baduser
# Send SIGHUP to nginx to reload config without restart
sudo pkill -HUP nginx# Start a process in the background
python3 server.py &
# Output: [1] 2847 (job number and PID)
# List background jobs in current shell
jobs
# [1]+ Running python3 server.py &
# Bring a background job to foreground
fg # bring most recent job to foreground
fg %1 # bring job number 1 to foreground
# Send current foreground process to background
# First: Ctrl+Z (suspends it)
# Then:
bg # resume it in background
bg %1 # resume job 1 in background
# nohup: run a command that survives terminal close
nohup python3 server.py > server.log 2>&1 &
# Output goes to server.log, process continues if you log outModern Linux systems use systemd as PID 1. It starts all services on boot and manages them throughout the system's life.
# Service management
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # reload config without full restart
# Enable/disable on boot
sudo systemctl enable nginx # start on boot
sudo systemctl disable nginx # do not start on boot
sudo systemctl enable --now nginx # enable AND start right now
# Check status
systemctl status nginx
# Output looks like this:
# nginx.service - A high performance web server
# Loaded: loaded (/lib/systemd/system/nginx.conf; enabled)
# Active: active (running) since Mon 2024-01-15 10:22:00 UTC
# Process: 1823 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
# Main PID: 1824 (nginx)
# Tasks: 2 (limit: 4915)
# Memory: 6.2M
# CPU: 42ms
# CGroup: /system.slice/nginx.service
# ├─1824 nginx: master process /usr/sbin/nginx
# └─1825 nginx: worker process
# List all services
systemctl list-units --type=service
systemctl list-units --type=service --state=failed
# View service logs
journalctl -u nginx # all logs for nginx
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -f # follow live logs
journalctl -b # all logs since last boot
journalctl -p err # only error and aboveWriting a simple systemd service:
# Create /etc/systemd/system/myapp.service
sudo nano /etc/systemd/system/myapp.service[Unit]
Description=My Python Application
After=network.target
[Service]
Type=simple
User=alice
WorkingDirectory=/home/alice/myapp
ExecStart=/usr/bin/python3 /home/alice/myapp/server.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target# Reload systemd to pick up new unit file, then start
sudo systemctl daemon-reload
sudo systemctl enable --now myappcron runs commands at scheduled times. The schedule is defined in a crontab file.
# Edit your crontab
crontab -e
# List your crontab
crontab -l
# Edit another user's crontab (as root)
sudo crontab -e -u aliceCrontab format — five time fields followed by the command:
# MIN HOUR DAY_OF_MONTH MONTH DAY_OF_WEEK COMMAND
# 0-59 0-23 1-31 1-12 0-7 (0,7=Sun)
# Run every day at 2:30am
30 2 * * * /usr/local/bin/backup.sh
# Run every Monday at 8am
0 8 * * 1 /usr/local/bin/weekly_report.sh
# Run every 15 minutes
*/15 * * * * /usr/local/bin/check_status.sh
# Run at midnight on the 1st of every month
0 0 1 * * /usr/local/bin/monthly_cleanup.sh
# Redirect cron output to a log file
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Exercise 1: Run ps aux --sort=-%cpu | head -15. Identify the top three processes by CPU. What do they do?
Exercise 2: Start sleep 300 & to create a background job. Use jobs to see it. Use fg to bring it foreground. Use Ctrl+Z to suspend it. Use bg to resume in background. Use kill %1 to terminate it.
Exercise 3: Check the status of the ssh service with systemctl status ssh. Note whether it is enabled on boot.
Exercise 4: Write a crontab entry that runs the command date >> /tmp/datelog.txt every minute. Wait 3 minutes, then check /tmp/datelog.txt. Then remove the crontab entry.
Previous: [Phase 4 — Users and Permissions](Phase-4-Users-and-Permissions) | Next: [Phase 6 — Networking](Phase-6-Networking)