Process Basics
Understanding processes is fundamental to Bash scripting. Every running program is a process with a unique Process ID (PID). Bash provides special variables to work with processes, allowing you to manage background jobs, track process IDs, and coordinate multiple processes. Mastering process basics is essential for building robust, efficient scripts that can handle concurrent operations!
Process IDs (PID)
Every process has a unique Process ID (PID). Bash provides special variables to access process IDs:
$$: PID of the current shell/script$!: PID of the last background process$PPID: Parent Process ID (the process that started this one)
Click Run to execute your code
# Get current process ID
echo "Current script PID: $$"
# Get parent process ID
echo "Parent PID: $PPID"
# Start background process and capture PID
sleep 10 &
bg_pid=$!
echo "Background process PID: $bg_pid"
-
$$ is the PID of the current shell/script-
$! stores the PID of the most recently started background process-
$PPID is the PID of the parent process- Process IDs are unique and sequential (incrementing)
Running Processes in Background
You can run commands in the background by appending & to the command. This allows your script to continue executing while the command runs.
# Run command in background
long_running_command &
# Capture the PID immediately after starting
sleep 60 &
bg_pid=$!
echo "Started process with PID: $bg_pid"
# Check if process is running
ps -p $bg_pid > /dev/null 2>&1 && echo "Process is running" || echo "Process finished"
$! variable updates after each background command, so store it in a variable right away!
Checking Process Status
You can check if a process is still running using the ps command or by checking the exit status:
# Check if process is running
pid=12345
if ps -p $pid > /dev/null 2>&1; then
echo "Process $pid is running"
else
echo "Process $pid has finished"
fi
# Wait for background process and check exit status
sleep 5 &
bg_pid=$!
wait $bg_pid
exit_status=$?
echo "Process $bg_pid exited with status: $exit_status"
Parent and Child Processes
When a script starts another process, the script is the parent and the new process is the child. Understanding this relationship is important for process management:
#!/bin/bash
# Parent process
echo "Parent PID: $$"
echo "Parent's parent PID: $PPID"
# Start child process
sleep 10 &
child_pid=$!
echo "Child process PID: $child_pid"
# In the child process context (if script calls itself or another script)
# $$ would be the child's PID
# $PPID would be this script's PID
Common Mistakes
1. Not capturing PID immediately
# Wrong - $! changes after each background command
sleep 10 &
sleep 5 & # $! now points to this, not the first sleep
pid=$!
echo "First sleep PID: $pid" # Wrong! This is the second sleep's PID
# Correct - capture immediately
sleep 10 &
first_pid=$!
sleep 5 &
second_pid=$!
echo "First: $first_pid, Second: $second_pid"
2. Assuming process is still running
# Wrong - process might have finished
sleep 10 &
pid=$!
# ... do other things ...
kill $pid # Might fail if process already finished
# Correct - check first
sleep 10 &
pid=$!
if ps -p $pid > /dev/null 2>&1; then
kill $pid
echo "Process killed"
else
echo "Process already finished"
fi
3. Confusing $$ and $!
# Wrong - $$ is current script, not background process
sleep 10 &
# Later...
kill $$ # Kills the script itself, not the background process!
# Correct - use $! or store PID
sleep 10 &
bg_pid=$!
# Later...
kill $bg_pid # Kills the background process
Exercise: Process Manager
Task: Create a script that starts multiple background processes and tracks them!
Requirements:
- Start 3 background processes (sleep commands with different durations)
- Store each PID in an array
- Display all PIDs
- Wait for all processes to complete
- Display a message when all are done
Show Solution
#!/bin/bash
# Process manager exercise
pids=()
# Start 3 background processes
sleep 3 &
pids+=($!)
sleep 5 &
pids+=($!)
sleep 2 &
pids+=($!)
echo "Started processes with PIDs: ${pids[@]}"
# Wait for all processes
for pid in "${pids[@]}"; do
wait $pid
echo "Process $pid completed"
done
echo "All processes finished!"
Summary
- $$: Current script/shell PID
- $!: Last background process PID
- $PPID: Parent Process ID
- &: Run command in background
- wait: Wait for background process to complete
- ps -p: Check if process is running
- Capture PID: Store
$!immediately after starting background process - Process Hierarchy: Scripts can be parents of child processes
What's Next?
Great! You've learned the basics of process management. Next, we'll dive deeper into Background Jobs - managing multiple background processes, job control with jobs, fg, bg, nohup, and disown. These advanced techniques give you fine-grained control over concurrent operations!
Enjoying these tutorials?