Skip to content

A simple Python tool to close off those pesky "Port in Use" errors through a force close.

License

Notifications You must be signed in to change notification settings

FyefoxxM/portkiller

Repository files navigation

Port Killer

Python Version License Platform

Find and kill processes hogging your ports

Because "port 3000 already in use" is rage-inducing.

Quick Start

# Install
pip install psutil

# Use
python portkiller.py 3000 --force

The Problem

You're trying to start your dev server. Node says port 3000 is already in use. You forgot what's running. You have to Google "how to find process using port" for the 47th time. You run some arcane lsof command you copy-pasted. You find the PID. You kill it. Five minutes wasted.

Port Killer does this in one command.

Installation

From GitHub (Recommended)

# Clone the repository
git clone https://github.com/YOUR-USERNAME/portkiller.git
cd portkiller

# Install dependencies
pip install -r requirements.txt

# Make it executable (optional)
chmod +x portkiller.py

# Test it
python portkiller.py 9999

Manual Installation

# Install dependency
pip install psutil

# Download portkiller.py
# Make it executable (optional)
chmod +x portkiller.py

See INSTALL.md for system-wide installation and troubleshooting.

Usage

Basic usage (with confirmation):

python portkiller.py 3000

Output:

πŸ” Checking port 3000...

πŸ“ Found 1 process(es) using port 3000:
  🟒 node (PID: 12345) - LISTEN

πŸ’€ Kill this process? (y/n):

Force mode (no confirmation):

python portkiller.py 3000 --force

Output:

πŸ” Checking port 3000...

πŸ“ Found 1 process(es) using port 3000:
  🟒 node (PID: 12345) - LISTEN

βœ… Killed node (PID: 12345)

πŸŽ‰ Successfully freed port 3000

Verbose mode (show connection details):

python portkiller.py 3000 --verbose

Output:

πŸ” Checking port 3000...

πŸ“ Found 1 process(es) using port 3000:
  🟒 node (PID: 12345) - LISTEN
      Local: 0.0.0.0:3000
      Remote: N/A

Check if port is free:

python portkiller.py 8080

Output:

πŸ” Checking port 8080...
βœ… Port 8080 is not in use

Options

  • port - Port number to check (required)
  • -f, --force - Kill without asking for confirmation
  • -v, --verbose - Show detailed connection information

How It Works

  1. Uses psutil to scan all network connections
  2. Finds processes listening on the specified port
  3. Gets process name and PID
  4. Kills the process (gracefully with SIGTERM, then SIGKILL if needed)
  5. Handles zombie processes correctly

Cross-Platform Support

Works on:

  • βœ… Linux
  • βœ… macOS
  • βœ… Windows

Uses Python's psutil library for cross-platform process management.

What Broke (And How I Fixed It)

Issue 1: Zombie Processes

Problem: After killing a process, psutil.pid_exists() would still return True because the process became a zombie (dead but not yet reaped by parent).

Solution: Check both PID existence AND process status. Accept STATUS_ZOMBIE as a successful kill.

if not psutil.pid_exists(pid):
    return True

# PID exists but might be zombie
p = psutil.Process(pid)
if p.status() == psutil.STATUS_ZOMBIE:
    return True  # It's dead, just waiting to be reaped

Issue 2: Permission Errors

Problem: In sandboxed environments or without proper permissions, psutil.net_connections() can't see all processes.

Solution: Catch AccessDenied exceptions and provide helpful error messages directing users to run with sudo/admin privileges.

Issue 3: System Tool Dependencies

Initial approach: Used lsof and netstat system commands.

Problem: Not available in all environments, different syntax across platforms.

Solution: Switched to psutil which handles cross-platform differences internally and works without system tools.

Limitations

  • Permissions: May need sudo/admin privileges to see or kill some processes
  • Network namespace: Only sees connections in the current network namespace
  • Port range: Only works with TCP/UDP ports (doesn't handle Unix sockets)

Stats

  • Lines of code: 197
  • Time to build: ~5 hours (including debugging zombie processes)
  • Dependencies: psutil only
  • Tested on: Linux (Ubuntu 24)

Real-World Use Cases

Web Development:

python portkiller.py 3000 --force  # React dev server
python portkiller.py 8000 --force  # Django server
python portkiller.py 5000 --force  # Flask server

Database Development:

python portkiller.py 5432 --force  # PostgreSQL
python portkiller.py 3306 --force  # MySQL
python portkiller.py 27017 --force # MongoDB

Before running tests:

# Kill any leftover test servers
python portkiller.py 8080 --force
npm run test

Why This Beats Manual Killing

Manual way:

# Linux/Mac
lsof -ti:3000 | xargs kill -9

# Windows
netstat -ano | findstr :3000
taskkill /PID <pid> /F

Problems with manual:

  • Have to remember different commands for different OS
  • Need to parse output yourself
  • No confirmation or safety checks
  • Easy to kill wrong process

Port Killer way:

python portkiller.py 3000

Benefits:

  • Works everywhere
  • Shows you what you're killing
  • Safe by default (confirmation required)
  • Pretty output with emojis
  • Handles multiple processes
  • Graceful shutdown by default

Making It Global

Add an alias to your shell config:

# ~/.bashrc or ~/.zshrc
alias pk="python /path/to/portkiller.py"

Then use it like:

pk 3000 -f

Or make it a proper command:

sudo ln -s /path/to/portkiller.py /usr/local/bin/portkiller

Then:

portkiller 3000 -f

Future Improvements (V2)

If I were to continue this project:

  • Multi-port support: portkiller 3000,8000,8080 -f
  • Range support: portkiller 3000-3010 -f
  • Process whitelist: Don't kill critical system processes
  • History: Remember what ports you killed recently
  • Auto-restart: Kill and restart the process
  • Port scanner: Find all ports in use on the system

But for V1, it does exactly what it needs to: kill that damn process hogging your port.

License

MIT - Do whatever you want with it. See LICENSE for details.

Contributing

Found a bug? Have an idea? Contributions welcome! See CONTRIBUTING.md for guidelines.

Project Structure

portkiller/
β”œβ”€β”€ portkiller.py          # Main script
β”œβ”€β”€ README.md              # You are here
β”œβ”€β”€ INSTALL.md             # Installation guide
β”œβ”€β”€ CONTRIBUTING.md        # Contribution guidelines
β”œβ”€β”€ LICENSE                # MIT License
β”œβ”€β”€ requirements.txt       # Python dependencies
β”œβ”€β”€ .gitignore            # Git ignore rules
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ usage_examples.sh  # Quick reference
β”‚   β”œβ”€β”€ common_ports.md    # Port reference guide
β”‚   └── test_portkiller.py # Integration tests
└── .github/
    └── workflows/
        └── ci.yml         # GitHub Actions CI

Acknowledgments

Built as part of the "30 for 30" challenge - 30 useful tools in 30 days.

Day 5: Port Killer βœ…

About

A simple Python tool to close off those pesky "Port in Use" errors through a force close.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors