How to kill processes running on a port only if the port is open? - linux

Currently, I am able to kill a process running on a port with:
//other scripts that should be executed
...........................
sudo kill $( sudo lsof -i:9005 -t )
...........................
//other scripts that should be executed
Now, I want to first test if the port 9005 is actually open and then only try to kill it.If the port is not open, I don't want to execute the kill script. I want to ensure that subsequent scripts are executed irrespective of whether the port is open or close. So, I am looking for something like:
//other scripts that should be executed
.............
<test-if-port-9005-is-open> && sudo kill $( sudo lsof -i:9005 -t )
.............
// other scripts that should be executed
How can I achieve this ?

You could do something like this:
nc -zv 127.0.0.1 9005 && sudo kill $( sudo lsof -i:9005 -t )
It kills the process if a tcp-connection was successful on the provided port. Then it moves on. As tested on macOS High Sierra.

If I understand your question correctly, the output of lsof -i:9005 -t will by definition be empty when the port is not open. xargs on Linux has an option for handling this:
sudo lsof -i:9005 -t | xargs -r sudo kill
or you can simply check the exit code of lsof; it will be non-zero to signal an error if it didn't find anything to report:
if pids=$(sudo lsof -i:9005 -t); then
sudo kill $pids
fi

Related

Why doesn't tcpdump run in background?

I logged in a virtual machine via ssh and I tried to run a script in background, the script is shown below:
#!/bin/bash
APP_NAME=`basename $0`
CFG_FILE=$1
. $CFG_FILE #just some variables
CMD=$2
PID_FILE="$PIDS_DIR/$APP_NAME.pid"
CUR_LOG_DIR=$LOGS_RUNNING
echo $$ > $PID_FILE
#Main script code
#This script shall be called using the following syntax
# $ nohup script_name output_dir &
TIMESTAMP=`date +"%Y%m%d%H%M%S"`
CAP_INTERFACE="eth0"
/usr/sbin/tcpdump -nei $CAP_INTERFACE -s 65535 -w file_result
rm $PID_FILE
The result should be tcpdump running in background, redirecting the command result to file_result.
The script is called with:
nohup $SCRIPT_NAME $CFG_FILE start &
And It is stopped calling the STOP_SCRIPT:
##STOP_SCRIPT
PID_FILE="$PIDS_DIR/$APP_NAME.pid"
if [ -f $PID_FILE ]
then
PID=`cat $PID_FILE`
# send SIGTERM to kill all children of $PID
pkill -TERM -P $PID
fi
When I check the file_result, after running the stop script, It is empty.
What is happening? How can I solve it?
I found this link: https://it.toolbox.com/question/launching-tcpdump-processes-in-background-using-ssh-060614
The author seems to have faced a similar issue. They debate about race conditions, but I didn't understand completely.
I'm not sure what you're trying to accomplish by having the startup script itself continue to run, but here's an approach that I think accomplishes what you're trying to do, namely start tcpdump and have it continue to run immune to hangups via nohup. I've simplified things a bit for illustrative purposes - feel free to add any variables back as you see fit, such as the nohup.out output directory, TIMESTAMP, etc.
Script #1: tcpdump_start.sh
#!/bin/sh
rm -f nohup.out
nohup /usr/sbin/tcpdump -ni eth0 -s 65535 -w file_result.pcap &
# Write tcpdump's PID to a file
echo $! > /var/run/tcpdump.pid
Script #2: tcpdump_stop.sh
#!/bin/sh
if [ -f /var/run/tcpdump.pid ]
then
kill `cat /var/run/tcpdump.pid`
echo tcpdump `cat /var/run/tcpdump.pid` killed.
rm -f /var/run/tcpdump.pid
else
echo tcpdump not running.
fi
To start tcpdump, just run tcpdump_start.sh.
To stop the tcpdump instance started with tcpdump_start.sh, just run tcpdump_stop.sh.
The captured packets will be written to the file_result.pcap file, and yes, it's a pcap file, not a text file, so it helps to name it with the proper file extension. The tcpdump statistics will be written to the nohup.out file when tcpdump is terminated.
I too had faced problems when running tcpdump over an SSH session.
In my case, I was running
sudo nohup tcpdump -w {pcap_dump_file} {filter} > /dev/null 2>&1 &
Where, running this command over Paramiko SSH session as a background process was the problem.
To get around this, I used screen utility of Linux.
screen is an easy to use tool for long-running of processes as a service.
Might be an old post, but this is also relevant. I couldn;t understand why no file was being created only to realise that the file might not be created until a certain amount of data had been captured.
https://github.com/the-tcpdump-group/tcpdump/issues/485

How to kill the port node env is using

I am collaborating on a deploy using sudo with ssh access to aws ec2 instance.
The application starts up and throws the error
Error: listen EADDRINUSE :::4000
if I do:
sudo fuser 4000/tcp
I get:
4000/tcp: 1669
If I do:
sudo fuser -i -k 4000/tcp
I get:
4000/tcp: 1669 Kill process 1669 ? (y/N)
If I do:
y
It doesn't kill the port. I have stopped the app as well of course.
I don't have netstat.
Is this a privilege thing with the root access? I would try to change the port number but don't have that access right now.
Is there anything else I can try?
thanks
You can do this using a combination of kill and lsof.
sudo kill -9 $(sudo lsof -t -i:4000)
Which tells the os to terminate the process using port 4000.
sudo You're likely going to need root level access
kill -9 tells the os to terminate the process
$(some command) command substitution
/ run the command
lsof -t implies terse output excluding
headers
lsof -i:PORT_NUMBER is used to filter the list by internet
address/port

listen EADDRINUSE: address already in use :::5000

In my application, I use concurrently to run both backend and front end simultaneously. After ctrl + c, strill the port 5000 is running. Also, port 3000 is running. I have to manually kill processes. How can I solve this?
Run cmd.exe as 'Administrator':
C:\Windows\System32>taskkill /F /IM node.exe
run pa -xa | grep node
you will get result with processid
4476 pts/0 Sl+ 0:01 node index.js
then kill the process with kill -9 4476
as simple as that
lsof -ti finds open files(sockets are files in nix based systems) -t removes the headers, so that we can pipe into kill(We just want the process id), -i lets lsof find the file based off the internet address. We do not have to provide the full address, we can just search by port, by using the pattern :port.
Some commands accept input from stdin, and we can pipe directly to them, kill is not one of those commands, so we must use xargs(It reads from stdin, and calls the specified command with the input from stdin).
Finally the ; lets us execute both commands irrespective of one another. Regardless of whether lsof -ti:3000 | xargs kill succeeds or fails,
lsof -ti:5000 | xargs kill will run, and vice versa.
lsof -ti:3000 | xargs kill; lsof -ti:5000 | xargs kill
Restart your laptop/server, it will release all the busy ports, then try again... you can also use
ps aux | grep node
and then kill the process using:
kill -9 PID..
You can kill all the processes that are using node it can also kill a system process
Not preferred: killall -9 node
but most of the times it wont work for nodemon, and didnt work for me.
You can fix this issue by killing the address in use or may simply restart your device.
1- For Linux to Kill the address in use, use the following command
sudo kill $(sudo lsof -t -i:8080)
where replace 8080 with your app address.
you can simply restart your laptop or change the port number it should work

how to terminate a process which is run with sudo? Ctrl+C do it, but not kill

At my company, some commands are allowed to run with sudo, such as tcpdump. Others not.
I expect run tcpdump for a while, and then stop it.
When I run tcpdump, and I could abort that with Ctrl+C
I wrote a shell script like this -
#!/bin/sh
sudo tcpdump -ieth1 -w ~/dump.bin
sleep 5
kill -2 $!
it doesn't really work. The process of tcpdump is run as root, and current user is a normal account.
My question is: is there any way to do the equivalent of ctrl c in bash script?.
EDIT:
ps:As my company's security policy, I cannot run kill as root.
Try the -Z option to tcpdump. It instructs tcpdump to drop root privileges and run as the user specified in the argument.
sudo tcpdump -Z $USER -ieth1 -w ~/dump.bin
Now try killing that process.
Simply run kill through sudo as well:
sudo kill -2 $!
This way the kill process will have the privilege to send signals to a process that runs as root.
For programs that don't have special switches like -Z and in case you can alter sudoers file, this is a solution:
sudo myprogram &
sleep 5
sudo pkill myprogram
All I have to do is to allow to run pkill myprogram passwordless by using visudo and adding this line:
myuser ALL=(ALL) NOPASSWD:/bin/pkill myprogram
This is less dangerous that lo let sudo kill any program.
The timeout command also terminates a program after so long. sudo timeout 5 tcpdump -ieth1 -w ~/dump.bin should accomplish the same thing as the script.
sudo tcpdump -Z root -w ~/dump.bin -n -i eth0 -G 300 -W 1
G - Timeout Seconds (After timeout period the comman gets killed automatically)
Z - drop root and runs as user privilege
W - Number files to be saved (as a splitted file)
sudo tcpdump -ieth1 -w ~/dump.bin
will block your script, you need to put it into the background:
sudo tcpdump -ieth1 -w ~/dump.bin &
.
This and the answer from Blagovest should do it.

Find (and kill) process locking port 3000 on Mac [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed last year.
The community reviewed whether to reopen this question 8 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
How do I find (and kill) processes that listen to/use my TCP ports? I'm on macOS.
Sometimes, after a crash or some bug, my Rails app is locking port 3000. I can't find it using ps -ef...
When running
rails server
I get
Address already in use - bind(2) (Errno::EADDRINUSE)
The same issue happens when stopping Node.js process. Even after the process is stopped and the app stops running, port 3000 is locked. When starting the app again, getting
Address already in use (Errno::EADDRINUSE)
You can try netstat
netstat -vanp tcp | grep 3000
For macOS El Capitan and newer (or if your netstat doesn't support -p), use lsof
lsof -i tcp:3000
Find:
sudo lsof -i :3000
Kill:
kill -9 <PID>
PLEASE NOTE: -9 kills the process immediately, and gives it no chance of cleaning up after itself. This may cause problems. Consider using -15 (TERM) or -3 (QUIT) for a softer termination which allows the process to clean up after itself.
Quick and easiest solution:
kill -9 $(lsof -ti:3000)
For multiple ports:
kill -9 $(lsof -ti:3000,3001)
#3000 is the port to be freed
Kill multiple ports with single line command:
kill -9 $(lsof -ti:3000,3001)
#Here multiple ports 3000 and 3001 are the ports to be freed
lsof -ti:3000
If the port is occupied, the above command will return something like this: 82500 (Process ID)
lsof -ti:3001
82499
lsof -ti:3001,3000
82499
82500
kill -9 $(lsof -ti:3001,3000)
Terminates both 82499 and 82500 processes in a single command.
For using this in package.json scripts:
"scripts": {
"start": "kill -9 $(lsof -ti:3000,3001) && npm start"
}
In terminal you can use:
npm run start
Nothing above worked for me. Anyone else with my experience could try the following (worked for me):
Run:
lsof -i :3000 (where 3000 is your current port in use)
then check status of the reported PID :
ps ax | grep <PID>
finally, "begone with it":
kill -QUIT <PID>
A one-liner to extract the PID of the process using port 3000 and kill it.
lsof -ti:3000 | xargs kill
The -t flag removes everything but the PID from the lsof output, making it easy to kill it.
This single command line is easy to remember:
npx kill-port 3000
You can also kill multiple ports at once:
npx kill-port 3000 3001 3002
For a more powerful tool with search:
npx fkill-cli
PS: They use third party javascript packages. npx comes built in with Node.js.
Sources: tweet | github
You can use lsof -i:3000.
That is "List Open Files". This gives you a list of the processes and which files and ports they use.
To forcefully kill a process like that, use the following command
lsof -n -i4TCP:3000
OR lsof -i:3000
Where 3000 is the port number the process is running at
this returns the process id(PID)
and run
kill -9 "PID"
Replace PID with the number you get after running the first command
Why kill -9 PID does not work?
If you trying to kill a process with its PID and it still runs on another PID, it looks like you have started that process in a different account most probably root account. so Login in with sudo su and kill it
In your .bash_profile, create a shortcut for terminate the 3000 process:
terminate(){
lsof -P | grep ':3000' | awk '{print $2}' | xargs kill -9
}
Then, call $terminate if it's blocked.
To kill multi ports.
$ npx kill-port 3000 8080 8081
Process on port 3000 killed
Process on port 8080 killed
Process on port 8081 killed
Hope this help!
lsof -P | grep ':3000' | awk '{print $2}'
This will give you just the pid, tested on MacOS.
Execute in command line on OS-X El Captain:
kill -kill `lsof -t -i tcp:3000`
Terse option of lsof returns just the PID.
One of the ways to kill a process on a port is to use the python library: freeport (https://pypi.python.org/pypi/freeport/0.1.9) . Once installed, simply:
# install freeport
pip install freeport
# Once freeport is installed, use it as follows
$ freeport 3000
Port 3000 is free. Process 16130 killed successfully
To view the processes blocking the port:
netstat -vanp tcp | grep 3000
To Kill the processes blocking the port:
kill $(lsof -t -i :3000)
Find and kill:
This single command line is easy and works correctly.
kill -9 $(lsof -ti tcp:3000)
Find the open connection
lsof -i -P | grep -i "listen"
Kill by process ID
kill -9 'PID'
Possible ways to achieve this:
top
The top command is the traditional way to view your system’s resource usage and see the processes that are taking up the most system resources. Top displays a list of processes, with the ones using the most CPU at the top.
ps
The ps command lists running processes. The following command lists all processes running on your system:
ps -A
You could also pipe the output through grep to search for a specific process without using any other commands. The following command would search for the Firefox process:
ps -A | grep firefox
The most common way of passing signals to a program is with the kill command.
kill PID_of_target_process
lsof
List of all open files and the processes that opened them.
lsof -i -P | grep -i "listen"
kill -9 PID
or
lsof -i tcp:3000
lsof -i tcp:port_number - will list the process running on that port
kill -9 PID - will kill the process
in your case, it will be
lsof -i tcp:3000 from your terminal
find the PID of process
kill -9 PID
I made a little function for this, add it to your rc file (.bashrc, .zshrc or whatever)
function kill-by-port {
if [ "$1" != "" ]
then
kill -9 $(lsof -ni tcp:"$1" | awk 'FNR==2{print $2}')
else
echo "Missing argument! Usage: kill-by-port $PORT"
fi
}
then you can just type kill-by-port 3000 to kill your rails server (substituting 3000 for whatever port it's running on)
failing that, you could always just type kill -9 $(cat tmp/pids/server.pid) from the rails root directory
These two commands will help you find and kill server process
lsof -wni tcp:3000
kill -9 pid
kill -9 $(lsof -ti:3000)
works for me on macOS always.
If you're working on a node.js project, you can add it to package.json scripts like;
"scripts": {
...
"killme": "kill -9 $(lsof -ti:3000)",
...
},
then
npm run killme
--
Also if you want to add system wide alias for your macOS, follow these steps;
Navigate to your home directory:
cd ~
Open up .bash_profile or zsh profile using nano or vim:
vi .bash_profile
Add an alias (press i):
alias killme="kill -9 $(lsof -ti:3000)"
save file
restart terminal
type killme to the terminal
Of course you can change port 3000 to what you want.
Add to ~/.bash_profile:
function killTcpListen () {
kill -QUIT $(sudo lsof -sTCP:LISTEN -i tcp:$1 -t)
}
Then source ~/.bash_profile and run
killTcpListen 8080
Using sindresorhus's fkill tool, you can do this:
$ fkill :3000
Works for me for terminating node (Mac OS Catalina)
killall -9 node
TL;DR:
lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill
If you're in a situation where there are both clients and servers using the port, e.g.:
$ lsof -i tcp:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 2043 benjiegillam 21u IPv4 0xb1b4330c68e5ad61 0t0 TCP localhost:3000->localhost:52557 (ESTABLISHED)
node 2043 benjiegillam 22u IPv4 0xb1b4330c8d393021 0t0 TCP localhost:3000->localhost:52344 (ESTABLISHED)
node 2043 benjiegillam 25u IPv4 0xb1b4330c8eaf16c1 0t0 TCP localhost:3000 (LISTEN)
Google 99004 benjiegillam 125u IPv4 0xb1b4330c8bb05021 0t0 TCP localhost:52557->localhost:3000 (ESTABLISHED)
Google 99004 benjiegillam 216u IPv4 0xb1b4330c8e5ea6c1 0t0 TCP localhost:52344->localhost:3000 (ESTABLISHED)
then you probably don't want to kill both.
In this situation you can use -sTCP:LISTEN to only show the pid of processes that are listening. Combining this with the -t terse format you can automatically kill the process:
lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill
Here's a helper bash function to kill multiple processes by name or port
fkill() {
for i in $#;do export q=$i;if [[ $i == :* ]];then lsof -i$i|sed -n '1!p';
else ps aux|grep -i $i|grep -v grep;fi|awk '{print $2}'|\
xargs -I# sh -c 'kill -9 #&&printf "X %s->%s\n" $q #';done
}
Usage:
$ fkill [process name] [process port]
Example:
$ fkill someapp :8080 node :3333 :9000
You can try this
netstat -vanp tcp | grep 3000
I use:
lsof -wni tcp:3000
Get the PID, and:
kill -9 <PID>
my fav one-liner:
sudo kill `sudo lsof -t -i:3000`
To kill port 3000 on mac, run the below command
kill -9 $(lsof -t -i:3000 -sTCP:LISTEN)

Resources