18

Given the following command lsof -i:1025 I get:

COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    12345 john   11u  IPv4 0xb2f4161230e18fd57      0t0  TCP localhost:foobar (LISTEN)

I am trying to write a script to get that PID (12345) and kill it. At the moment I have to run lsof -i:1025, get that PID and then run kill -9 12345.

Zack
  • 2,377
  • 4
  • 25
  • 51

6 Answers6

49

The lsof(8) man page says:

   -t       specifies that lsof should produce terse output with process
            identifiers only and no header - e.g., so that the output
            may be piped to kill(1).  -t selects the -w option.

You can use lsof -t -i:1025 | xargs kill -9.

fabianopinto
  • 1,825
  • 15
  • 22
8

Something like:

#!/bin/bash --

x=`lsof -Fp -i:1025`
kill -9 ${x##p}

Should do it. The 3rd line runs lsof using the -F option to get just the pid, with a leading p. The next line drops the leading p from the output of lsof and uses the result as the pid in a kill command.

Edit: At some point lsof was modified so the file descriptor preceded by an f is always output, whether you ask for it or not (which makes no sense to me, but what do I know). While you could put a | grep '^p' in the back quotes, an easier way is to use the -t option, as noted in fabianopinto's answer below.

blm
  • 2,379
  • 2
  • 20
  • 24
  • What is the `${x##p}` syntax ? – CodyBugstein Dec 24 '20 at 03:55
  • I get an error: `kill: illegal pid: 13013\nf22` – CodyBugstein Dec 24 '20 at 04:05
  • @CobyBugstein `${x##p}` is bash's pattern matching parameter expansion syntax. It matches the pattern `p` in `$x` and deletes the longest occurrence of it. In this case it matches the `p` at the start of the line and deletes it. On your other question, that's due to a change to `lsof` since I wrote my answer. I'll edit my answer to note that. – blm Dec 24 '20 at 21:48
  • 1
    Thanks! It seems to work as well with only one `#` btw – CodyBugstein Dec 25 '20 at 06:20
2

man lsof says that you can use -F to specify fields to to be output for processing by other programs. So you can do something like

lsof -i:1025 -Fp | sed 's/^p//' | xargs kill -9
jayant
  • 2,349
  • 1
  • 19
  • 27
2

Further to @blm's answer, it didn't work for me exactly because the output of the lsof command was:

p4679
f33

So with the ${x##p} was

4679
f33

The solution

Grab only the first line with | head -n 1:

x=`lsof -Fp -i:"$1" | head -n 1`
kill -9 ${x##p}
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Yes, `lsof` was changed at some point after I wrote my answer to always include the file descriptor on a line starting with `f`, whether you asked for it or not. I've updated my answer to note that. – blm Dec 24 '20 at 21:52
2

And furthermore from @blm's and @Mosh Feu's answers:

lsof -i:1337 -Fp | head -n 1 | sed 's/^p//' | xargs kill

is what ended up doing the trick for me.

I recommend adding this as a bash function and aliasing it

alias kbp='killByPort'
killByPort() {
  lsof -i:$1 -Fp | head -n 1 | sed 's/^p//' | xargs kill
}
rsmets
  • 789
  • 1
  • 13
  • 23
0

This shortcut will kill the process quickly for you

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

for fish shell users, simply remove the $ sign, so

kill -9 (lsof -t -i :3000)
KhaledMohamedP
  • 5,000
  • 3
  • 28
  • 26