Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

3.3.2. Job Control, Signals, and Scheduling

💡 First Principle: Job control is the shell's mechanism for managing multiple processes in a single terminal session — pausing them, backgrounding them, and bringing them back to the foreground. Signals are the kernel's mechanism for sending asynchronous notifications to processes. They're related but distinct: job control uses signals internally (SIGSTOP, SIGCONT, SIGHUP), but signals can be sent to any process, not just shell jobs.

Signals — The Key Ones for XK0-006:
SignalNumberDefault ActionUse Case
SIGHUP1TerminateReload config without restart (many daemons)
SIGINT2TerminateCtrl+C — user interrupt
SIGKILL9Terminate (force)Last resort — bypasses handlers
SIGTERM15Terminate (graceful)Default kill signal — preferred
SIGSTOP19StopPause process (cannot be caught)
SIGCONT18ContinueResume stopped process
kill 1234                        # Send SIGTERM (default) to PID 1234
kill -15 1234                    # Explicit SIGTERM
kill -9 1234                     # SIGKILL (force)
kill -1 1234                     # SIGHUP (reload config)
kill -l                          # List all signal names and numbers
killall nginx                    # Send SIGTERM to all processes named nginx
pkill -u alice                   # Kill all processes owned by alice
pkill -SIGHUP nginx              # Send SIGHUP to all nginx processes
Job Control:
./long_script.sh &               # Start directly in background
Ctrl+Z                           # Suspend current foreground job (SIGSTOP)
bg                               # Resume suspended job in background
bg %2                            # Resume job number 2 in background
fg                               # Bring most recent background job to foreground
fg %1                            # Bring job 1 to foreground
jobs                             # List all jobs for current shell session
jobs -l                          # Include PIDs

nohup ./script.sh &              # Run in background, immune to terminal close (SIGHUP)
nohup ./script.sh > output.log 2>&1 &   # Capture output

nohup is essential for long-running commands started over SSH — without it, closing the SSH session sends SIGHUP to the shell, which propagates to child processes, killing your job.

Scheduling — cron, anacron, and at:
# crontab
crontab -e                       # Edit current user's crontab
crontab -l                       # List current user's crontab
crontab -r                       # Remove current user's crontab
crontab -u alice -e              # Edit alice's crontab (root)

# Cron format: minute hour day-of-month month day-of-week command
# ┌───────── minute (0-59)
# │ ┌───────── hour (0-23)
# │ │ ┌───────── day of month (1-31)
# │ │ │ ┌───────── month (1-12)
# │ │ │ │ ┌───────── day of week (0-7, 0 and 7 = Sunday)
# │ │ │ │ │
  0 2 * * * /usr/bin/backup.sh          # Daily at 02:00
  */15 * * * * /usr/bin/check.sh        # Every 15 minutes
  0 0 1 * * /usr/bin/monthly.sh         # First day of each month at midnight

# anacron — for systems not running 24/7 (runs missed jobs on next boot)
# Configuration: /etc/anacrontab
# Format: period  delay  job-id  command
  7    10   weekly-backup   /usr/bin/backup.sh

# at — run once at a specific time
at 14:30                         # Opens interactive prompt
at now + 2 hours                 # 2 hours from now
echo "/usr/bin/report.sh" | at midnight
atq                              # List pending at jobs
atrm 3                           # Remove at job #3
Process Limits:
ulimit -a                        # Show all limits for current shell
ulimit -n 65536                  # Set max open file descriptors (current session)
# Persistent limits: /etc/security/limits.conf
# alice hard nofile 65536
# alice soft nofile 32768

⚠️ Exam Trap: nohup alone does not background the process — it only prevents SIGHUP. You must also append & to actually run it in the background: nohup ./script.sh &. Without &, nohup still runs in the foreground and blocks your terminal.

Reflection Question: You start a long database backup over SSH: pg_dump mydb > backup.sql. Your SSH connection drops halfway through. The backup process is killed. What two changes to the command would prevent this from happening again?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications