How to Kill All User Processes Except Current Terminal Session in Linux


4 views

Every Linux user eventually discovers the nuclear option kill -9 -1 which terminates all processes owned by the current user. However, this includes your current terminal session - essentially cutting the branch you're sitting on. Here's why this happens:


# This terminates EVERYTHING including your terminal:
kill -9 -1

The solution involves intelligent process filtering. We'll use pgrep to identify processes while excluding:

  1. The current shell process ($$)
  2. The terminal emulator process
  3. Any critical session managers

Here's the most robust implementation I've used in production environments:


#!/bin/bash
# Get current terminal PID and parent terminal process
TERM_PID=$(ps -o ppid= -p $$)
SHELL_PID=$$

# Kill all user processes except these
kill -9 $(pgrep -u $USER | grep -vw -e $SHELL_PID -e $TERM_PID -e $(pgrep -P $TERM_PID))

For different use cases, consider these approaches:


# Method 1: Using pkill with exclusions
pkill -u $USER -P 1 --signal SIGKILL -v -P $$

# Method 2: Using procfs directly
kill -9 $(ls /proc/ \
  | grep '^[0-9]' \
  | awk -v me=$UID -v shell=$$ '$1 != shell && $1 != PPID {print $1}' \
  | xargs -r ps -o pid= -p 2>/dev/null)

Always test with -SIGTERM first before using -SIGKILL:


# Dry run first
pkill -u $USER -P 1 --signal SIGTERM -v -P $$

# Then force kill if needed
pkill -9 -u $USER -P 1 -v -P $$

If you're working with tmux or screen sessions, modify the exclusion pattern:


# Preserve tmux/screen sessions
SCREEN_PID=$(ps -o ppid= -p $(pgrep -u $USER tmux\\|screen))
kill -9 $(pgrep -u $USER | grep -vw -e $$ -e $TERM_PID -e $SCREEN_PID)

Many Linux users discover the kill -9 -1 command as a quick way to terminate all their processes. However, this nuclear option has an obvious drawback - it kills the terminal session itself, making it impractical for interactive use.

Here's a safer approach that preserves your current terminal while terminating other processes:

# Get current terminal's process ID
CURRENT_TERM=$(ps -p $$ -o ppid= | tr -d ' ')

# Kill all user processes except current terminal and its children
pkill -u $USER -P 1 -v -P $CURRENT_TERM

This approach works by:

  1. Identifying the parent process ID (PPID) of your current terminal session
  2. Using pkill with the -v (invert match) flag to exclude processes with that PPID
  3. The -P 1 ensures we target processes initiated by the user

For systems without pkill, you can use this killall alternative:

# Get current shell's process tree
CURRENT_TREE=$(pstree -p $$ | grep -o '[0-9]\+' | tr '\n' ',' | sed 's/,$//')

# Kill all user processes not in the current tree
killall -u $USER -r -v "($CURRENT_TREE)"

To make this command easily accessible, add this to your ~/.bashrc:

alias killother='pkill -u $USER -P 1 -v -P $(ps -p $$ -o ppid= | tr -d " ")'
  • This will terminate all background jobs, SSH sessions, and detached processes
  • Running GUI applications may be affected depending on your desktop environment
  • Always test in a non-production environment first

For systems with unusual process hierarchies, you might need to adjust the parent process filtering. This version handles more complex cases:

# Get entire process ancestry
TERM_ANCESTORS=$(pstree -ps $$ | grep -o '[0-9]\+' | tr '\n' '|' | sed 's/|$//')

# Kill everything except ancestry
pgrep -u $USER | grep -vE "($TERM_ANCESTORS)" | xargs kill -9