The case for shell job control
Job control—fg, bg, Ctrl+Z, and friends—often feels like a relic from before terminal multiplexers and tabbed terminal windows. But there are solid, practical reasons to reach for it, even when you have tmux or a tab-friendly terminal at hand. The basics are straightforward: a process in your terminal runs in the foreground (the default), in the background (started with some_process &, still executing but not accepting input), or in a stopped state (paused via Ctrl+Z, not using CPU, but ready to resume). Job control is the toolkit for moving processes between those states and inspecting what’s running.
The core commands are few:
fgmoves a stopped or background process into the foreground.bgrestarts a stopped process in the background.Ctrl+Zpauses the current foreground process.jobslists the active jobs for your terminal session.kill(the shell builtin) sends a signal to a job, e.g.,kill -9 %2for an unresponsive process.disowndrops a job from the shell’s job list so it survives your terminal closing.waitblocks until background jobs finish—mostly useful in scripts.
You can address a specific job using its number from jobs output—for instance, fg %2 brings job number 2 back to the foreground. The %2 syntax is not a simple variable expansion; the shell builtin kill parses it directly, typically by expanding it to a PID via a helper like jobs -p %2 before delegating to the system kill command.
When job control actually shines
Dealing with Ctrl+C-resistant processes. When a foreground process ignores Ctrl+C, you don’t have to hunt for it in another tab. Press Ctrl+Z to stop it, then kill %1 (or kill -9 %1 if it’s truly wedged). It’s a fast, targeted way to clean up misbehaving programs.
Recovering from a premature Ctrl+Z. Accidentally pausing your editor or a long-running command is a rite of passage. The fix is a single command—fg—to resume it. Similarly, if you hit Ctrl+S and freeze your terminal, Ctrl+Q usually unfreezes it.
Running background utilities alongside interactive work. With job control you can keep the output of a tool like tcpdump running in the background while you execute a command in the foreground, and see both outputs interleaved in the same terminal. This can be clearer than switching between tabs to compare timestamps.
Pausing CPU-heavy tasks. If ffmpeg is maxing out your cores but you don’t want to lose its progress, Ctrl+Z suspends it instantly. When you need the CPU back, fg or bg resumes the work.
Handling state and output cleanly
A common scenario: you start a GUI application like Wireshark from the shell without an &. If you don’t want it to occupy your terminal tab, press Ctrl+Z followed by bg to send it to the background, then optionally disown it so it won’t be killed when you close the session. The same approach applies to long-running jobs you started without tmux—though reclaiming and redirecting output after the fact can be tricky and may require Linux-specific tools like reptyr or reredirect to move or rewire a running process.
Within a terminal editor like vim, Ctrl+Z lets you pause the editor, run a quick shell command, and return with fg. This is handy for fast builds or tests without ever leaving the terminal’s context.
In constrained environments and personal preference
There are also cases where job control isn’t just a convenience—it’s the only option. Single-user mode, heavily restricted systems, or SSH sessions without tmux or screen leave job control as your sole process manager, and it avoids spawning extra SSH connections.
Finally, some people simply prefer job control over tab juggling. Being able to see all your terminal windows on screen while backgrounding overflow processes keeps focus on your active work. And if you’ve carefully set up environment variables for a task, using one shell’s job control avoids recreating that setup from scratch in new tabs.
Useful patterns worth adopting
A few practical workflows emerge from all this. For an unresponsive process, the Ctrl+Z then kill %1 sequence beats hunting through process lists. Pausing a job with Ctrl+Z when you need CPU headroom is cleaner than killing it and losing work. And running a diagnostic tool like tcpdump in the background—with jobs and fg at your fingertips—can bring clarity to debugging that tab-switching muddles.



