Linux Package Management & Job Control – Practice Exercises

Published: (December 26, 2025 at 06:33 PM EST)
7 min read
Source: Dev.to

Source: Linux Package Management – Job Control Practice Exercises (Dev.to)

Exercise 1 – Job vs Process

Goal

Understand what a job is versus a process in Bash, and why a pipeline counts as a single job.

Background

  • Process – an instance of a running program, identified by a PID.
  • Job – a collection of one or more processes that Bash manages together (e.g., a pipeline).
  • Bash assigns each job a job ID (%1, %2, …) that you can refer to with job‑control built‑ins (fg, bg, jobs, kill).

Part 1 – Bash Jobs & Process Control

1️⃣ List the current jobs

jobs
  • If no jobs are shown, start a few background tasks first (see step 2).

2️⃣ Start some background jobs

# Simple sleep commands
sleep 60 &          # Job %1
sleep 120 &        # Job %2

# A pipeline (counts as a single job)
yes | head -n 1000000 > /dev/null &
  • Verify the jobs with jobs -l to see both the job ID and the PID(s).

3️⃣ Bring a job to the foreground

fg %1   # Replace %1 with the desired job ID
  • Observe that the command now occupies the terminal until it finishes or you suspend it (Ctrl+Z).

4️⃣ Suspend a foreground job and resume it in the background

# While a job is running in the foreground, press Ctrl+Z
# Bash will report something like: [1]+  Stopped   sleep 60

bg %1   # Resume the stopped job in the background
  • Use jobs -p to list only the PIDs of the background jobs.

5️⃣ Terminate a job

kill %2          # Sends SIGTERM to job %2
kill -9 %2       # Force‑kill if it doesn’t exit gracefully
  • Confirm the job is gone with jobs.

6️⃣ Verify that a pipeline is a single job

# Start a pipeline in the background
{ yes | head -n 500000 > /dev/null; } &
jobs -l
  • Bash reports one job ID, even though the pipeline creates two processes (yes and head). Both PIDs are listed under the same job.

Summary Checklist

  • List jobs with jobs and jobs -l.
  • Start background jobs using &.
  • Use fg to bring a job to the foreground.
  • Suspend with Ctrl+Z and resume with bg.
  • Terminate jobs using kill.
  • Observe that a pipeline counts as a single job.

Further Reading

  • Bash Reference Manual – Job Control
  • man bashJOB CONTROL section
  • man kill, man fg, man bg, man jobs

Exercise 1 – Job vs Process (Foreground job)

Goal

Understand what a job is versus a process, and why pipelines count as a single job.

Task

ping -c 5 google.com | wc -l

Observe

  • Two processes are created: ping and wc.
  • One job is created: the whole pipeline is treated as a single command.

Why it matters

  • Bash job control operates on jobs, not on individual processes.
  • Knowing this helps when debugging or managing pipelines.

Exercise 2 – Foreground Job Blocking the Shell

Task

ping google.com

Run the command and then try typing another command.

Observe

  • The shell is blocked.
  • All keyboard input is sent to the ping process.

Stop It

Press Ctrl + C.

Production Relevance

Long‑running foreground commands can block automation scripts and prevent further commands from executing.

Exercise 3 — Background Job (&)

Task

ping -c 10 google.com &

Observe

  • The shell returns to the prompt immediately.
  • The ping output continues to appear asynchronously.

Check the job list

jobs

Why it matters

Running commands in the background without proper output handling can clutter the terminal or log files. Use job control (jobs, fg, bg, kill) or redirect output as needed.

Exercise 4 – Redirect Background Output

Task

ping -c 10 google.com > ping.log &

Observe

  • No terminal noise.
  • Output captured safely in ping.log.

Production relevance

Redirecting output for background jobs is a standard practice in production environments.

Exercise 5 — Using /dev/null

Task

ping google.com > /dev/null &

Observe

  • The command’s output is discarded completely.

Why

Handy for health‑check or keep‑alive scripts where you don’t need any output.

Exercise 6 — Job Listing

Task

jobs

Start multiple jobs

ping google.com > /dev/null &
ping bing.com   > /dev/null &

Observe

Job IDs ([1], [2], …) appear.

Exercise 7 – Bringing a Job to the Foreground (fg)

Task

fg %1

Stop it

Press Ctrl + C.

Key rule

Only foreground jobs receive keyboard signals.

Exercise 8 — Suspending a Job (Ctrl + Z)

Task

ping google.com
# press Ctrl+Z
jobs

Observe

Job state: Stopped.

Exercise 9 — Resume Job in Background (bg)

Task

bg %1
jobs

Observe

  • The job runs again.
  • It still does not accept keyboard input.

Exercise 10 — Killing a Job

Task

kill %1

Force kill

kill -9 %1

Production relevance

Safely terminating runaway jobs.

Exercise 11 — wait Command

Task

ping -c 5 google.com > /dev/null &
ping -c 5 bing.com   > /dev/null &
wait
echo "All jobs finished"

Observe

echo runs only after the two ping commands finish.

Why

Demonstrates parallel‑execution control in shell scripts using wait.

Exercise 12 – wait -n (any job finishes)

Task

ping -c 10 google.com > /dev/null &
ping -c 3 bing.com   > /dev/null &
wait -n
echo "One job finished"

Exercise 13 — Notification with Terminal Bell

Task

ping -c 5 google.com > /dev/null &
wait
tput bel
echo "Download complete"

Why?
Provides an audible cue when a long‑running manual task finishes.

Exercise 14 — nohup Survival After Logout

Task

nohup ping -c 30 google.com > nohup.out &
exit
  1. Log in again.
  2. Verify that the ping process is still running:
ps aux | grep ping

Observation

The ping job continues to run after you log out.

Production Relevance

Useful for remote‑server operations that must persist after the user session ends (e.g., long‑running scripts, background services).

Exercise 15 — Parent Process Change (Re‑parenting)

Task

ps -o pid,ppid,cmd -p <pid>

Observe

After logout, the parent PID changes to 1 (the init process).

Part 2 — RPM (Low‑Level Package Management)

Exercise 16 – Inspect RPM Without Installing

rpm -qpl zsh*.rpm

Lists the files that would be installed by the package.

Exercise 17 — Manual RPM Install

sudo rpm -i zsh*.rpm

No dependency resolution is performed.

Exercise 18 – RPM Removal

sudo rpm -e zsh

Demonstrates why using RPM alone can be dangerous in production (no automatic handling of dependencies or configuration files).

Part 3 — DNF Core Usage

Exercise 19 — Search Packages

dnf search links

Exercise 20 — Install with Dependencies

sudo dnf install links

Exercise 21 — Remove Package

sudo dnf remove links

Exercise 22 — Repository Awareness

dnf info neofetch

Shows which repository provides the package.

Part 4 — Repositories (BaseOS, AppStream, …)

Exercise 23 – List Repositories

dnf repolist

Exercise 24 – Enable CRB

sudo dnf config-manager --set-enabled crb

Exercise 25 – Enable EPEL

sudo dnf install epel-release

Install htop

sudo dnf install htop

Part 5 – Dependency Analysis

Exercise 26 – What a Package Provides

dnf repoquery --provides bash

Exercise 27 – What a Package Requires

dnf repoquery --requires bash

Exercise 28 – Who Requires a Package

dnf repoquery --whatrequires bash

Exercise 29 – Weak Dependencies (Recommends)

dnf repoquery --recommends gimp

Exercise 30 – Install Without Weak Dependencies

sudo dnf install gimp --setopt=install_weak_deps=False

Exercise 31 – Backward Weak Dependencies (Supplements)

dnf repoquery --what-supplements langpacks-de

Part 6 — Dependency Removal Dangers

Exercise 32 — Dependency Auto‑Removal Problem

# Install Matplotlib (which pulls in NumPy)
sudo dnf install python3-matplotlib

# Verify NumPy works
python3 -c "import numpy"

# Remove Matplotlib
sudo dnf remove python3-matplotlib

# Verify NumPy again
python3 -c "import numpy"

The application breaks after removing python3-matplotlib because numpy was installed as a dependency and was automatically removed with it.

Exercise 33 — Fix Using dnf mark install

# Install NumPy explicitly
sudo dnf install python3-numpy

# Mark it as a manually‑installed package so it isn’t auto‑removed
sudo dnf mark install python3-numpy

# Now remove Matplotlib safely
sudo dnf remove python3-matplotlib

By marking python3-numpy as a manually‑installed package, it remains on the system even when its dependent package (python3-matplotlib) is removed.

Part 7 – Updates, Downgrades, & Version Locking

Exercise 34 – System Upgrade

sudo dnf upgrade

Exercise 35 – Downgrade a Package

  1. List all available versions of the package:

    dnf list python3 --showduplicates
  2. Downgrade to the desired version (replace <VERSION> with the exact release you want):

    sudo dnf downgrade python3-<VERSION>

Exercise 36 – Temporary Upgrade Exclusion

sudo dnf upgrade --exclude=python3*

Part 8 – Automatic Updates

Exercise 37 – Enable Automatic Updates

  1. Install the dnf-automatic package:

    sudo dnf install dnf-automatic
  2. Enable and start the timer:

    sudo systemctl enable --now dnf-automatic.timer

Exercise 38 – Configure Security‑Only Updates

  1. Open the configuration file for editing:

    sudo vi /etc/dnf/automatic.conf
  2. Set the following options (place them under the appropriate section, e.g., [commands]):

    upgrade_type = security
    apply_updates = yes

Note: The new settings take effect the next time the timer runs. To apply updates immediately, you can run sudo dnf-automatic --upgrade.

Part 9 — DNF Modules

Exercise 39 – List Modules

dnf module list

Exercise 40 – Enable Node.js Stream

sudo dnf module enable nodejs:18
sudo dnf upgrade
node --version

Exercise 41 – Install Module Profile

sudo dnf module install nodejs:18/development

Exercise 42 – Remove Module Profile

sudo dnf module remove nodejs:18/development

Exercise 43 – Disable & Reset Module

sudo dnf module disable nodejs
sudo dnf module reset nodejs

Part 10 — Dependency Conflict Debugging

Exercise 44 — Broken RPM Install

sudo dnf install https://example.com/foreign.rpm

Analyze

Identify missing dependencies with:

dnf repoquery --whatprovides <package-name>

Part 11 — Snap Packages

Exercise 45 – Install Snap

sudo dnf install snapd
sudo systemctl enable --now snapd.socket

Exercise 46 – Install Firefox via Snap

sudo snap install firefox
snap run firefox

Exercise 47 – Compare Versions

firefox --version
snap run firefox --version

The Snap version of Firefox is newer.

Back to Blog

Related posts

Read more »