Linux Process Management Practical: Beyond Killing - Safe Multi-Process Operations
Building on the "observe → verify → stop" decision pattern from the basics article, this practical guide covers:
- Alternatives to killing (background execution, nice)
- Operating on multiple processes at once (pkill, killall)
- Handling errors (Operation not permitted, etc.)
Table of Contents
The Practical Decision Pattern
When a Process Is in the Way, Think in This Order
- Can I move it to the background? (If I just need the terminal)
- Can I lower its priority? (If it's just CPU-heavy)
- If it must be stopped, start with TERM
"Killing" is just one of many options.
Keep It Running: Background Execution
Start in Background from the Beginning
$ long_command &
Adding & at the end runs the command in the background.
Continue After SSH Disconnection
$ nohup long_command &
With nohup, the process continues running after logout.
▶ About nohup Output
When using nohup, standard output is automatically written to nohup.out.
# To explicitly specify output destination $ nohup long_command > output.log 2>&1 &
This records both standard output and standard error to output.log.
Job Control: Ctrl+Z / bg / fg
Use this when you want to "pause a running command and use the terminal."
Basic Flow
# 1. Suspend the running command Ctrl+Z # 2. Resume in background $ bg # 3. Or bring back to foreground $ fg
When You Have Multiple Jobs
# Check job list $ jobs [1]- Stopped vim file.txt [2]+ Running ./script.sh & # Operate by job number $ fg %1 # Bring vim to foreground
Key Decision Point
- Ctrl+Z = Suspend (process is still alive)
- Ctrl+C = Attempt to terminate (sends SIGINT)
If you just want your terminal back, Ctrl+Z → bg keeps things running.
Multi-Process Operations: pkill / killall
When multiple processes share the same name, specifying PIDs one by one is tedious.
pkill: Operate by Name
# Send SIGTERM to all processes named python $ pkill python # Force kill (last resort) $ pkill -9 python
killall: Also Operates by Name
$ killall python
⚠️ Note: Name Matching Differences
- pkill: Partial match (python → also matches python3)
- killall: Exact match
To avoid stopping unintended processes, verify with pgrep first.
# Check targets beforehand $ pgrep -l python 1234 python3 5678 python
Slow It Down Instead: nice / renice
Instead of "killing" a CPU-heavy process, lower its priority to let other tasks run first.
nice: Set Priority at Launch
# Run with low priority (higher number = lower priority) $ nice -n 10 ./heavy_script.sh
renice: Change Priority of Running Process
# Lower priority of PID 1234 $ renice +10 -p 1234
Nice Value Range
- -20: Highest priority (requires root)
- 0: Default
- +19: Lowest priority
Note: Lower numbers mean higher priority.
▶ When to Use This?
Situations Where nice/renice Is Effective
- A backup script is running in the background, but you want other work prioritized
- A build process is heavy, but you don't want to stop it
- You want to set low priority for overnight batch jobs from the start
Priority adjustment is effective for processes you can't afford to restart.
Handling Errors: Operation not permitted
What to do when kill or pkill returns "Operation not permitted."
Cause and Solution
$ kill 1234 bash: kill: (1234) - Operation not permitted
Main Causes of This Error
- Trying to stop another user's process
- Trying to stop a system process (started by root)
Solution
# First, check the process owner $ ps aux | grep 1234 # If it's not your process, you need sudo $ sudo kill 1234
⚠️ Before Using sudo
Using root privileges to kill means you might affect the system.
Verify "why isn't this my process" before proceeding.
Real-World Scenarios
Scenario 1: Need the Terminal While vim Is Open
Ctrl+Z # Suspend vim $ bg # Move to background (vim stays suspended) $ fg # Return to vim after other work
Scenario 2: Multiple Python Processes Running Wild
# 1. Verify targets $ pgrep -l python 1234 python3 5678 python3 # 2. Send SIGTERM to all $ pkill python # 3. Force kill if any remain $ pkill -9 python
Scenario 3: Build Is Heavy but Can't Be Stopped
# Find the build process PID $ pgrep -l make 1234 make # Lower its priority $ renice +15 -p 1234
Scenario 4: Need Process to Continue After SSH Disconnect
# Start with nohup from the beginning $ nohup ./long_script.sh > log.txt 2>&1 & # Or detach a running job $ disown %1
Summary: The Practical Decision Flow
When a Process Is in the Way
- Just need the terminal → Ctrl+Z → bg
- Just CPU-heavy → renice to lower priority
- Must be stopped → kill (SIGTERM)
- Still won't stop → kill -9 (last resort)
"Killing" should be your last choice.
📊 Complete Process Management Series
- Basics - The ps / top / kill Decision Pattern
- Practical (This Article) - Job Control, pkill, nice
📋 Verification Environment
Commands in this article were verified on Ubuntu 24.04 LTS / bash 5.2.