Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Learning the Linux Command Line lsof and awk by Killing a Process that Hold a Port

Posted on: 2023-09-19

Goal and Context

Developing web applications and services requires opening ports on a machine. In some situations, a process using a port might die without releasing the port -- the process is dead but runs in the background, keeping the port reserved. Thus, the solution is to kill the process. Sometimes, some ports might be used by many different processes in different periods of time. Therefore, having a process keeping a port in hostage happens. The solution is to find the process who is holding the port and killing it.

In this article, we will use lsof to find the process of who is holding the port and using kill -9 to kill it. A third tool is needed to combine the information of lsof into kill, which is awk.

Finding the process id by a port number: Lsof

The command line lsof is natively available in Linux. The letters of the tool are for "LiSt Open File".

The trick is to use the -i which allows to find a file that matches a specific address. Many combinations vary for ipv4 or ipv6 or different protocols. In my case, the port I want to kill most of the time is for a web server, a docker container, or a port used in Visual Studio Code (VsCode) for debugging. They are all using tcp. Thus, using lsof -i tcp:9229 gives the information.

lsof -i tcp:9229

COMMAND PID USER FD TYPE DEVICE
node 19005 pdesjardins 26u IPv4 ox033434234

The output is simplified but has the information needed: the PID.

The pid is the process identifier that is needed to pass to the next command line.

Grabbing the last line: Tail

The tail command line allows to read a specific line from the end of a file. A file can be the output of a command line. Using tail is a way to skip the header of the lsof. The following command uses the option -n 1, which returns the last line.

lsof -i tcp:9229 | tail -n 1

node 19005 pdesjardins 26u IPv4 ox033434234

Grabbing a record: Awk

The awk command scans for a pattern. Awk has an option to scan each tab. The PID is on the second record (tab).

lsof -i tcp:9229 | tail -n 1 | awk '{print $2}' 

19005

Knowing your Tools

As I wrote this blog post, I looked further the lsof documentation and found out about -t option. The option provides a terse output with only the pid, meaning that the information can be piped to kill. It means that tail and awk can be removed by using:

lsof -i tcp:9229 -t

Killing the process: Kill

The kill command sends a signal to a process using a PID. Killing with kill -9 <pid here> instantly kills the process. However, another tool is needed to inject the PID into a command argument: xargs.

xargs: Passing the PID from Lsof to Kill

The last step is to send the process id to kill from the lsof. The xargs executes a command line and can use a pattern to replace a string by a value. In our case, the pattern is {pid} and will be replaced by the piped PID. The xargs uses the -I to specify the string to replace. Then, the command is specified with its option. The command needs to use the string, for example, {pid}, which will be replaced by the value piped. If more than one value is passed, then the command will be executed several times with each value.

The final script:

lsof -i tcp:9229 -t | xargs -I {pid} kill -9 {pid}

Conclusion

Ultimately, three tools were needed: lsof, xargs and kill. Learning about the tool helped to reduce the complexity by removing two additional tools (tail and awk).