Django: Stop a backgrounded runserver with lsof

A pony carrying on without supervision.

Update (2024-01-04): Added -sTCP:LISTEN to the command, to avoid stopping the browser in the case when a page load is in progress.

If you start runserver but your terminal session gets closed, the server can continue running in the background. For example, this can happen when your IDE crashes. This situation is annoying because you can’t stop the backgrounded runserver with Ctrl-C.

You can find and stop the server with your operating system’s process list tool, such as Windows Task Manager or macOS’ Activity Monitor. But this is manual and slow.

It’s faster to use this shell one-liner, for Bash or Zsh, on macOS or Linux:

lsof -i :8000 -sTCP:LISTEN -t | xargs -t kill

Replace “8000” with the port the server is running on.

lsof is pre-installed on macOS but you may need to install it on Linux. xargs is pre-installed everywhere.

Here’s a quick breakdown of what’s going on:

  1. lsof is a tool for listing processes and the files they have open.

    Since operating systems treat internet addresses as files, lsof has the -i option to select processes by the internet addresses they have open. -i :8000 selects processes using port 8000. -sTCP:LISTEN then narrows the list to processes listening on the given port, ignoring any open browser connections:

    $ lsof -i :8000 -sTCP:LISTEN
    COMMAND     PID        USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    python3.1 43282 adamjohnson    9u  IPv4 0xe72dc161b280a8a9      0t0  TCP localhost:irdmi (LISTEN)
    
  2. Adding -t makes lsof outputs only process IDs:

    $ lsof -i :8000 -sTCP:LISTEN -t
    43282
    
  3. xargs runs a named command for each line of its input. In this case the named command is kill, which signals processes to stop, and the input is the list of process IDs from lsof.

  4. xargs -t prints the commands it runs, so you can see if any process IDs get stopped:

    $ lsof -i :8000 -sTCP:LISTEN -t | xargs -t kill
    kill 43282
    

    If there are no matching processes, there will be no output:

    $ lsof -i :8000 -sTCP:LISTEN -t | xargs -t kill
    

Fin

Thanks to Lance Goyke for inspiring this post with his version without lsof.

May you never need to restart to stop background processes,

—Adam


Learn how to make your tests run quickly in my book Speed Up Your Django Tests.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: ,