87

I want to define a bash alias named kill3000 to automate the following task:

$ lsof -i:3000

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
ruby    13402 zero    4u  IPv4 2847851      0t0  TCP *:3000 (LISTEN)

$ kill -9 13402
SamB
  • 9,039
  • 5
  • 49
  • 56
Jonathan
  • 10,936
  • 8
  • 64
  • 79

6 Answers6

122
alias kill3000="fuser -k -n tcp 3000"
SamB
  • 9,039
  • 5
  • 49
  • 56
  • 4
    The reason I chose this as the answer is because I later found that `lsof -i:3000` can bring back multiple processes when I access the server in the web browser (e.g.): `ruby 587 zero 10u IPv4 2239530 0t0 TCP localhost:3000->localhost:45341 (ESTABLISHED) firefox 26843 zero 63u IPv4 2238948 0t0 TCP localhost:45337->localhost:3000 (ESTABLISHED)` I found that, `fuser -n tcp 3000` most accurately brings back the original process and so, probably would be the most reliable to use. – Jonathan Feb 08 '12 at 21:24
  • 8
    One thing I noticed was that fuser doesn't differentiate between local and remote connections - so I think if you ever had a process connected to a remote port 3000 it'd get killed too. For what it's worth. – synthesizerpatel Feb 09 '12 at 03:49
  • 3
    Note that `fuser` sends a SIGKILL by default. You can tell it to use a different signal with for instance: `fuser -k -TERM -n tcp 3000`. – Stephane Chazelas Feb 12 '14 at 08:39
  • For some reason, this does not work for me. After I issue the command and I do netstat -tulpn | grep 8001 , I still get the pid of the process. I am trying to kill a tcp port listening process - fuser -k -n tcp 8001 – user590849 Mar 27 '15 at 16:25
  • 8
    Doesn't work on OSX: `Unknown option: k` `Unknown option: n` – Dmitri Zaitsev Jan 15 '16 at 14:25
  • Juans-MacBook-Pro:ui-app jjalonso$ fuser -k -n tcp 9009 Unknown option: k Unknown option: n fuser: [-cfu] file ... -c file is treated as mount point -f the report is only for the named files -u print username of pid in parenthesis – jjalonso Nov 30 '16 at 10:53
  • It doesnt work for me either. I have a nodemon process running on 8080. If I open new terminal and run this, it gives me a pid, but when I go to chrome, I can still see the API on 8080 port. Not to mention the nodemon process doesnt get killed either in previous terminal. – theprogrammer Jul 31 '21 at 00:41
73

Try this:

kill -9 $(lsof -i:3000 -t)

The -t flag is what you want: it displays PID, and nothing else.

Update

In case the process is not found and you don't want to see error message:

kill -9 $(lsof -i:3000 -t) 2> /dev/null

Assuming you are running bash.

Update

Basile's suggestion is excellent: we should first try to terminate the process normally will kill -TERM, if failed, then kill -KILL (AKA kill -9):

pid=$(lsof -i:3000 -t); kill -TERM $pid || kill -KILL $pid

You might want to make this a bash function.

Pablo Bianchi
  • 1,824
  • 1
  • 26
  • 30
Hai Vu
  • 37,849
  • 11
  • 66
  • 93
12

Another option using using the original lsof command:

lsof -n -i:3000 | grep LISTEN | awk '{ print $2 }' | uniq | xargs kill -9

If you want to use this in a shell script, you could add the -r flag to xargs to handle the case where no process is listening:

... | xargs -r kill -9
Niklas B.
  • 92,950
  • 18
  • 194
  • 224
  • Don't forget the -r on xargs. :p – synthesizerpatel Feb 06 '12 at 22:57
  • synthesizerpatel: I personally don't too much care about that `not enough arguments` message. It's not like `kill` would go crazy and shoot your init process if it doesn't get input (correct me if I'm wrong ;) – Niklas B. Feb 06 '12 at 23:03
  • 1
    If you have something like this in a shell script with 'set -e', or '#!/usr/bin/bash -e', the failure of kill would cause the entire script to fail. My motto is: succeed quietly if you can, fail elegantly if you have to - but always return a useful exit code. – synthesizerpatel Feb 06 '12 at 23:05
  • @synthesizerpatel: True, but if I'd only use that from the command line ("automate the routine"), I'd actually like to see whether something was killed or not, and that's a simple way to achieve this :) Inside a shell script I'd probably add `-r` or use `|| true`, so I could at least see the error message. – Niklas B. Feb 06 '12 at 23:10
  • Heh. I only ran across this because I tested the lsof version.. If you have a service that binds to multiple interfaces, the lsof method will yield two identical PIDs as well. I'm not picking on you - I swear to god. Never saw the lsof -i:NNNN flag before. Oh, the other thing I'd suggest is '-n' so that lsof doesn't try to reverse-lookup any of the hosts. – synthesizerpatel Feb 06 '12 at 23:18
  • @synthesizer: Thanks, I'll add `-n`, `uniq`, and (optinally) `-r` :P – Niklas B. Feb 06 '12 at 23:37
  • One more optimization I think.. lsof -t -i4TCP:8090 -sTCP:LISTEN, which can be further tuned using the IP address, like so lsof -t -i4TCP@localhost:8090 -sTCP:LISTEN. That should also guarantee only one result. – synthesizerpatel Feb 07 '12 at 00:00
  • @synthesizerpatel: Thanks, but that's a bit too verbose IMHO and doesn't really improve functionality very much (after all, I don't know exactly what OP wants, I basically copy-and-pasted his already known-to-work command line). – Niklas B. Feb 07 '12 at 00:03
5

fuser -k 3000/tcp should also work

Dmitriusan
  • 11,525
  • 3
  • 38
  • 38
4

How about

alias kill3000="lsof -i:3000 | grep LISTEN | awk '{print $2}' | xargs kill -9"
dgw
  • 13,418
  • 11
  • 56
  • 54
3
fuser -n tcp 3000

Will yield the output of

3000/tcp:     <$pid>

So you could do:

fuser -n tcp 3000 | awk '{ print $2 }' | xargs -r kill
synthesizerpatel
  • 27,321
  • 5
  • 74
  • 91
  • I'm pretty sure this usage of `awk` is unnecessary and fails anyway. Playing with the `fuser` output, I eventually realized that what appears as the first column is actually stderr. – Brian Peterson Sep 27 '13 at 21:15