How to access the PID from an lsof. - bash

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.

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.

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.

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

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}

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
}

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)

Related

Killing a running sh script using pid

I have made an Auto Clicker and was wondering how i would kill it using
kill [pid]
My auto Clicker works like this:
while true [1]; do
xdotool click --repeat 10000 --delay 150 1
done
code I have used to try and terminate running proccess:
ps -ef | grep AutoClicker | grep -v grep | xargs kill -9
I found this code on another post, however i have had no luck with it.
pkill -f AutoClicker or kill $(pgrep -f AutoClicker)
If you run your code:
ps -ef | grep AutoClicker | grep -v grep | xargs kill -9
you should get an error message from kill.
kill expects a list of process ids not usernames, times, and random strings.
You need to filter out everything except the pids with something like:
ps -ef | grep AutoClicker | grep -v grep | awk '{print $2}' | xargs kill
Instead of searching for the process ID, use your own "PID file". I'll demonstrate with sleep in place of xdotool.
echo $$ > /tmp/my.pid
while true [1]; do
echo "clicking"
sleep 5
done
# rm -f /tmp/my.pid
I can run this script in another terminal window or the background. The important thing is that /tmp/my.pid contains the process ID of this running script. You can stop it with:
kill $(</tmp/my.pid)
This interrupts the while-loop. Need to figure out how to remove the PID file...

how to assign terminal variable from previous command's output

I'm very very new to the terminal script world. Here's what I want to do:
1) Find out the process that's using a given port (8000 in this case)
2) Kill that process
Pretty simple. I can do it manually using:
lsof -i tcp:8000 -- get the PID of what's using the port
kill -9 $PID -- terminate the app using the port
For reference, here's exactly what gets returned when using lsof -i tcp:8000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php 94735 MyUser 5u IPv6 0x9fbd127eb623aacf 0t0 TCP localhost:irdmi (LISTEN)
Here's my problem: how do I capture the PID value from lsof -i tcp:8000 so that I can use that variable for the next command? I know how to create variable that I assign... just not ones that are dynamically made.
The thing you’re looking for is called command substitution. It lets you treat the output of a command as input to the shell.
For example:
$ mydate="$(date)"
$ echo "${mydate}"
Mon 24 Feb 2014 22:45:24 MST
It’s also possible to use `backticks` instead of the dollar sign and parentheses, but most shell style guides recommend avoiding that.
In your case, you probably want to do something like this:
$ PID="$(lsof -i tcp:8000 | grep TCP | awk '{print $2}')"
$ kill $PID
Something along these lines should work:
lsof -i tcp:8000 | grep TCP | read cmd pid restofline
kill -9 $pid
before using the kill command, just echo it to make sure.

Killing processes SHELL

This command ps -ef | grep php returns a list of processes
I want to kill in one command or with a shell script all those processes
Thanks
The easiest way to kill all commands with a given name is to use killall:
killall php
Note, this only sends an interrupt signal. This should be enough if the processes are behaving. If they're not dying from that, you can forcibly kill them using
killall -9 php
The normal way to do this is to use xargs as in ps -ef | grep php | xargs kill, but there are several ways to do this.
ps -ef lists all processes and then you use grep to pick a few lines that mention "php". This means that also commands that have "php" as part of their command line will match, and be killed. If you really want to match the command (and not the arguments as well), it is probably better to use pgrep php.
You can use a shell backtick to provide the output of a command as arguments to another command, as in
kill `pgrep php`
If you want to kill processes only, there is a command pkill that matches a pattern to the command. This can not be used if you want to do something else with the processes though. This means that if you want to kill all processes where the command contain "php", you can do this using pkill php.
Hope this helps.
You can find its pid (it's on the first column ps prints) and use the kill command to forcibly kill it:
kill -9 <pid you found>
Use xargs:
ps -ef | grep php | grep -v grep | awk '{print $2}' | xargs kill -9
grep -v grep is exclude the command itself and awk gives the list of PIDs which are then passed kill command.
Use pkill php. More on this topic in this similar question: How can I kill a process by name instead of PID?

How do I count specific processes on Mac OS X?

Using a Mac, what would be the best way to count the number of instances of a particular process I am running? This is for a script I am writing to find the number of ffmpeg processes running on my machine.
Should I be using top here? ps aux|grep ffmpeg? What would be the best way to get the number?
grep -c will count occurrences:
count=`ps aux | grep -v "grep" | grep -c ffmpeg`
echo $count
ps aux | grep ffmpeg | wc -l will get you the number of processes that mention the phrase 'ffmpeg' you'll need to minus 1 on this value as ps aux | grep ffmpg is a process also.
You're looking for the program called "wc" -- "wc -l" will count lines for you.
"man wc" for details.
You can try the killall command on the Mac:
$ killall -s ffmpg
kill -TERM 20148
kill -TERM 20146
kill -TERM 20140
The -s means just list what you'd do, but don't actually kill any processes. Pipe it to wc, and you should get your result:
$ killall -s ffmpg | wc -l
3
In a shell script, you can do something like this:
num_of_processes=$(killall -s ffmpg | wc -l)
pgrep:
$ pgrep -c ffmpeg
If you don't use pgrep then mere grep might produce false positives.
To avoid it you could try -C option:
$ ps -C ffmpeg -o pid= | wc -l
Check that your ps version interprets it correctly.

How to find processes based on port and kill them all? [duplicate]

This question already has answers here:
How to kill a process running on particular port in Linux?
(34 answers)
Closed 5 years ago.
Find processes based on port number and kill them all.
ps -efl | grep PORT_NUMBER | kill -9 process_found_previously
how to complete the last column?
The problem with ps -efl | grep PORT_NUMBER is that PORT_NUMBER may match other columns in the output of ps as well (date, time, pid, ...). A potential killing spree if run by root!
I would do this instead :
PORT_NUMBER=1234
lsof -i tcp:${PORT_NUMBER} | awk 'NR!=1 {print $2}' | xargs kill
Breakdown of command
(lsof -i tcp:${PORT_NUMBER}) -- list all processes that is listening on that tcp port
(awk 'NR!=1 {print $2}') -- ignore first line, print second column of each line
(xargs kill) -- pass on the results as an argument to kill. There may be several.
1.) lsof -w -n -i tcp:8080
2.) kill -9 processId
kill $( lsof -i:6000 -t )
Or if you need permissions:
sudo kill $( sudo lsof -i:6000 -t )
Propose to use fuser command:
fuser -k -TERM -n tcp ${PORT_NUMBER}
sudo fuser -k 8080/tcp
An easy one to remember.
This syntax is probably much more recent than the date of the question!
... | awk '{ print $4 }' | xargs kill -9
please test with "echo" instead of "kill" before running
To kill all processes listening on a particular port, e.g. port 8864
kill -9 $ \`lsof -i:8864 -t\`
Replace 8864 by the port you want.

Resources