Viewing Processes
Viewing Processes
ps Command
# List all processes for current user
ps aux
# Full format with nice output
ps -ef
# Filter specific processes
ps aux | grep nginx
ps aux | grep '[n]ginx' # Avoids matching grep itself
# Show process tree
ps -ef --forest
pstree
pstree -p # Include PIDs
# Show processes for a specific user
ps -u www-data
# Show specific columns
ps -eo pid,ppid,user,%cpu,%mem,cmd --sort=-%cpu | head -20
# Find parent of a process
ps -o ppid= -p 1234
# Show all threads of a process
ps -Lf -p 1234
top and htop
# Interactive process viewer
top
# Key top commands:
# P - sort by CPU
# M - sort by memory
# k - kill a process (enter PID)
# q - quit
# 1 - show per-CPU stats
# H - show threads
# c - show full command
# Non-interactive top (for scripts)
top -bn1 | head -20
# htop (enhanced top)
htop
# Filter by user in htop
htop -u www-data
# Sort by memory in htop
htop --sort-key=PERCENT_MEM
Process Information from /proc
# View process details
cat /proc/1234/status | head -20
cat /proc/1234/cmdline | tr '\0' ' '
echo
cat /proc/1234/environ | tr '\0' '\n' | head -10
# View open files for a process
ls -la /proc/1234/fd/ | head -20
# View memory map
cat /proc/1234/maps | head -10
# View network connections
cat /proc/1234/net/tcp
Other Useful Commands
# Real-time I/O monitoring
iotop
# Real-time network monitoring
nethogs # Bandwidth per process
nload # Network interface load
# List open files and sockets
lsof -p 1234
lsof -i :8080 # Who's using port 8080?
lsof +D /var/log/ # Who's using files in /var/log?
# Show process resource usage
time ls /var/log/
# real 0m0.003s
# user 0m0.001s
# sys 0m0.002s
# strace - trace system calls
strace -p 1234 -e trace=network # Trace network calls
strace -c ls /tmp # Count system calls
Managing Processes
Managing Processes
Signals
# List all signals
kill -l
# Common signals:
# SIGHUP (1) - Reload configuration (daemon reload)
# SIGINT (2) - Interrupt (Ctrl+C)
# SIGQUIT (3) - Quit with core dump
# SIGKILL (9) - Force kill (unblockable)
# SIGTERM (15) - Graceful termination (default)
# SIGUSR1 (10) - User-defined signal 1
# SIGUSR2 (12) - User-defined signal 2
# SIGSTOP (19) - Pause process
# SIGCONT (18) - Resume paused process
Killing Processes
# Graceful shutdown (default signal: SIGTERM)
kill 1234
kill -15 1234
# Force kill (use only if graceful fails)
kill -9 1234
kill -KILL 1234
# Send SIGHUP (reload config, used by nginx, etc.)
kill -HUP 1234
# Kill all processes matching a name
pkill nginx
pkill -9 nginx # Force kill all nginx processes
# Kill by pattern with more control
pgrep -f 'python.*server' | xargs kill
# Kill all background jobs in shell
kill $(jobs -p)
Process Priority
# Start with higher priority (lower nice value = higher priority)
# Nice values range from -20 (highest) to 19 (lowest)
sudo nice -n -10 /usr/local/bin/myapp
# Change priority of running process
renice -5 -p 1234 # Set to -5
sudo renice -10 -p 1234 # Need root for negative values
# View nice value
ps -eo pid,ni,cmd | grep nginx
# Start with specific scheduling policy
sudo chrt -f 50 /usr/local/bin/realtime-app # FIFO, priority 50
Background and Foreground Jobs
# Run in background
mycommand &
# List background jobs
jobs -l
# Bring job to foreground
fg %1
# Send to background
bg %1
# Disown a job (remove from shell job list)
disown %1
# Run command immune to hangups
nohup mycommand &
# Run in a screen/tmux session
tmux new -d -s deploy 'mycommand'
Practical Examples
# Find and kill zombie processes
ps aux | awk '{if ($8=="Z") print $2, $11}'
# Kill parent of zombie
kill -9 $(ps -o ppid= -p <zombie_pid>)
# Find process using too much memory
ps aux --sort=-%mem | head -10
# Kill all processes using more than 1GB RSS
ps -eo pid,rss,cmd | awk '$2 > 1048576 {print $1}' | xargs kill
# Limit memory of a process at runtime (cgroups)
sudo cgcreate -g memory:mygroup
echo 536870912 | sudo tee /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
sudo cgexec -g memory:mygroup mycommand
Systemd Services
Systemd Services
systemctl Basics
# List all services
systemctl list-units --type=service
# Check service status
systemctl status nginx
# Start/stop/restart services
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # Reload config without downtime
# Enable/disable at boot
sudo systemctl enable nginx
sudo systemctl disable nginx
# Enable and start
sudo systemctl enable --now nginx
# Check if a service is running
systemctl is-active nginx
systemctl is-enabled nginx
Creating a Custom Service
# Create service file
sudo tee /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My Application
After=network.target
Wants=postgresql.service
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=60
# Environment
Environment=NODE_ENV=production
Environment=PORT=8080
EnvironmentFile=/opt/myapp/.env
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/log/myapp /var/lib/myapp
# Resource limits
LimitNOFILE=65536
MemoryMax=1G
CPUQuota=200%
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target
EOF
# Reload and enable
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
Viewing Logs
# View service logs
journalctl -u nginx
journalctl -u nginx -f # Follow (like tail -f)
journalctl -u nginx --since '1 hour ago'
journalctl -u nginx --since '2024-01-01' --until '2024-01-02'
# View all logs since last boot
journalctl -b
# View kernel messages
journalctl -k
# View logs for a specific PID
journalctl _PID=1234
# View logs by priority
journalctl -p err # Only errors
journalctl -p warning..err
# Disk usage of journal
journalctl --disk-usage
# Vacuum old logs
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=30d
Systemd Timers (Alternative to Cron)
# Create a timer
sudo tee /etc/systemd/system/backup.timer << 'EOF'
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=3600
[Install]
WantedBy=timers.target
EOF
# Create the matching service
sudo tee /etc/systemd/system/backup.service << 'EOF'
[Unit]
Description=Backup service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root
EOF
# Enable and start timer
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer
# List timers
systemctl list-timers
systemctl list-timers --all
# Test the service manually
sudo systemctl start backup.service
Cron Jobs
Cron Jobs
Crontab Syntax
# ┌───── minute (0-59)
# │ ┌───── hour (0-23)
# │ │ ┌───── day of month (1-31)
# │ │ │ ┌───── month (1-12)
# │ │ │ │ ┌───── day of week (0-7, 0 and 7 = Sunday)
# * * * * * command
Crontab Commands
# Edit crontab
crontab -e
# List current crontab
crontab -l
# List another user's crontab
sudo crontab -u deploy -l
# Remove all cron jobs for current user
crontab -r
# Check cron logs
grep CRON /var/log/syslog
journalctl -u cron
Cron Examples
# Run every minute
* * * * * /usr/local/bin/check.sh
# Run every 5 minutes
*/5 * * * * /usr/local/bin/check.sh
# Run every hour at minute 0
0 * * * * /usr/local/bin/hourly.sh
# Run daily at 2:30 AM
30 2 * * * /usr/local/bin/daily.sh
# Run weekly (Sunday at 3 AM)
0 3 * * 0 /usr/local/bin/weekly.sh
# Run monthly (1st at 4 AM)
0 4 1 * * /usr/local/bin/monthly.sh
# Run Mon-Fri at 9 AM
0 9 * * 1-5 /usr/local/bin/workday.sh
# Run every 15 minutes, but only on weekdays
*/15 * * * 1-5 /usr/local/bin/workday-check.sh
# Run with specific environment
MAILTO=admin@example.com
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# Anacron alternative (for systems that reboot often)
# /etc/anacrontab:
# 1 5 daily.backup /usr/local/bin/backup.sh
# 7 25 weekly.cleanup /usr/local/bin/cleanup.sh
Complete Cron Example
# Edit crontab
crontab -e
# Add:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=ops@example.com
# System monitoring - every 5 minutes
*/5 * * * * /usr/local/scripts/monitor.sh >> /var/log/monitor.log 2>&1
# Log rotation - daily at 1 AM
0 1 * * * /usr/sbin/logrotate /etc/logrotate.conf
# Database backup - daily at 2 AM
0 2 * * * /usr/local/scripts/db-backup.sh >> /var/log/db-backup.log 2>&1
# SSL certificate check - weekly
0 0 * * 0 /usr/local/scripts/check-ssl.sh
# Docker cleanup - Sunday at 3 AM
0 3 * * 0 /usr/bin/docker system prune -f >> /var/log/docker-prune.log 2>&1
# Reboot server - first of month at 4 AM (if needed)
0 4 1 * * /sbin/reboot