shell script to kill the process listening on port 3000?

86,433

Solution 1

alias kill3000="fuser -k -n tcp 3000"

Solution 2

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.

Solution 3

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

Solution 4

How about

alias kill3000="lsof -i:3000 | grep LISTEN | awk '{print $2}' | xargs kill -9"

Solution 5

fuser -k 3000/tcp should also work

Share:
86,433

Related videos on Youtube

Jonathan
Author by

Jonathan

Full-Stack Web-Developer specialising in PHP, JavaScript and Ruby utilising the Laravel, Vue.js, Ruby on Rails and Nuxt.js frameworks with MySQL/MariaDB and PostgreSQL databases. I also have experience in system architecture design, UI design and server automation & deployment on Ubuntu with and without dependence on tools such as Laravel Envoy and Ruby's Capistrano.

Updated on September 11, 2021

Comments

  • Jonathan
    Jonathan over 2 years

    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
    
    • Basile Starynkevitch
      Basile Starynkevitch over 12 years
      Why do you want an alias and not a bash function?
    • Basile Starynkevitch
      Basile Starynkevitch over 12 years
      I would make a function which first do a kill -TERM then do a kill -KILL because it is un-proper to kill processes without giving them the opportunity to terminate properly...
    • Jonathan
      Jonathan about 6 years
      @SteveChambers how is this a duplicate when it was written before the answer it is linked to? Absurd...
  • synthesizerpatel
    synthesizerpatel over 12 years
    Don't forget the -r on xargs. :p
  • Niklas B.
    Niklas B. over 12 years
    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 ;)
  • synthesizerpatel
    synthesizerpatel over 12 years
    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.
  • Niklas B.
    Niklas B. over 12 years
    @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.
  • synthesizerpatel
    synthesizerpatel over 12 years
    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.
  • Niklas B.
    Niklas B. over 12 years
    @synthesizer: Thanks, I'll add -n, uniq, and (optinally) -r :P
  • synthesizerpatel
    synthesizerpatel over 12 years
    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.
  • Niklas B.
    Niklas B. over 12 years
    @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).
  • Basile Starynkevitch
    Basile Starynkevitch over 12 years
    I would suggest kill -TERM first, then kill -KILL
  • Jonathan
    Jonathan over 12 years
    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.
  • synthesizerpatel
    synthesizerpatel over 12 years
    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.
  • Brian Peterson
    Brian Peterson over 10 years
    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.
  • Stephane Chazelas
    Stephane Chazelas over 10 years
    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.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com over 9 years
    I would also use tcp as in lsof -i tcp:3000 in scripts to be more precise.
  • user590849
    user590849 about 9 years
    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
  • Dmitri Zaitsev
    Dmitri Zaitsev over 8 years
    Doesn't work on OSX: Unknown option: k Unknown option: n
  • jjalonso
    jjalonso over 7 years
    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
  • theprogrammer
    theprogrammer almost 3 years
    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.