Computers didn’t always multi-task. Back then it was easy to identify an out of control process (hint: it was the only one running). These days, the moment you boot up your computer, you’re immediately running hundreds of processes. Every so often your fan will kick up to 11 and just like days of yore, there’s probably only a single rogue process to blame. Other times you go to
up a development server only to find that something else is already using the same port, but you have no idea which process.
Ready to go sleuthing? Let’s talk about tracking down processes, all from the command-line!
🐊 Alligator.io recommends ⤵Fullstack Advanced React & GraphQL by Wes Bos
This article assumes you’re on a Unix-like operating system and the tools discussed are already available to you. Sometimes we’ll need to use super user privileges, which hopefully you have as well.
None of the commands in this guide are destructive in nature. All we’re going to do is figure out the process ID of running processes. The process ID can be used for destructive purposes, like killing the job, but that’s for another article.
Arguably the easiest way to find out the ID of a process is by running
While not as elegant as some of the examples we’re going to go over, it’s often times more than enough to get you what you need:
Which will greet you a text-based process list similar to your favorite process explorer or activity monitor.
If this is your first time seeing
top, it’s probably a lot to take in.
There’s information about users, up-time, system load, available CPU and memory and then below it all, a nice list of processes.
It should look similar to this:
top - 18:51:41 up 10 days, 21:37, 3 users, load average: 0.44, 0.41, 0.66 Tasks: 252 total, 1 running, 251 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.3 us, 0.6 sy, 0.0 ni, 97.9 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st MiB Mem : 32046.7 total, 15190.6 free, 3999.7 used, 12856.4 buff/cache MiB Swap: 30517.6 total, 30162.4 free, 355.2 used. 26809.4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8383 josh 20 0 809168 92024 72892 S 1.7 0.3 6:23.94 spotify 767 root 20 0 1924628 20336 3468 S 0.7 0.1 24:17.07 containerd 1217 josh 20 0 249872 36296 16636 S 0.7 0.1 277:54.68 Xorg 1262 josh 20 0 3550872 311932 109312 S 0.7 1.0 321:50.42 gnome-shell 11371 josh 20 0 492308 53716 37984 S 0.7 0.2 0:45.78 gnome-terminal- 756 root 20 0 1890252 45104 10644 S 0.3 0.1 27:54.94 dockerd 14727 josh 20 0 13576 4064 3204 R 0.3 0.0 0:00.03 top 32562 josh 20 0 1349028 362364 181136 S 0.3 1.1 2:17.46 brave 1 root 20 0 198492 7424 5412 S 0.0 0.0 8:58.26 systemd
The list of processes is probably jumping around quite a bit, due to how you have things sorted. The default behavior is to sort the processes by the amount of CPU being used. Because of this, a processes eating up all of your CPU will be right there at the top.
If you look to the left of the process list, you’ll see a column labeled
PID. That columns is where you will find the process ID. In example above, process
8383 belongs to the
spotify command. If my Spotify app was getting unruly, I could take care of business knowing that ID.
It’s worth noting that a lot of applications are multi-threaded and have multiple processes running at once. Web browsers are pretty notorious for this.
Just because an processes’ ID doesn’t mean you have the main thread’s ID. If you were to kill the process ID for Chrome and it’s not the main thread’s ID, you’d probably end up killing a single tab, or extension and not the whole thing.
Let’s say that I already had a suspicion that my Spotify app was being unruly. By knowing the name of the command, in this case
spotify, I could use the
pidof command to get the process ID:
$ pidof spotify
pidof will list all of the processes that match the name. As mentioned earlier, a process may have multiple threads, so you may have to root around a bit to determine if you have the main thread or not.
Remember that Unix-like systems may recycle process IDs, so the
PID order is not a good indicator for deducing which ID may belong to the main thread.
Thus far, we’ve been finding jobs in the global scope of our system. Sometimes you have a process running in the background of your current session that you need to track down.
To help simulate some tasks in our session, let’s run the following:
$ sleep 300 & $ sleep 600 & $ sleep 900 &
This will run the
sleep command for 5, 10 and 15 minutes and throw each process into the background of our current session.
You probably noticed each of those commands returned a number that looks very similar to the process IDs we’ve been working with. As it turns out, when you background a process, you are given the process ID so you can return to it later.
For the sake of example, let’s say we didn’t know those process IDs and wanted to see the processes in our current session:
Which returns the currently running jobs in the session, the order of which they were run and their status. But wait, no process ID?!
To get the process ID to show up as well, you need to include the
$ jobs -p
Giving us results that probably look similar to this:
 15765 running sleep 300  - 15773 running sleep 600  + 15782 running sleep 900
Everything discussed thus far has helped us to identify rogue processes and processes that were backgrounded in our current session. One of the most frustrating things is trying to run a process or bring up a service only to find out that another process is already occupying the port.
Sure, you could just reboot your machine, but what’s the fun in that?
To easily track down which process is listening on a specific port, you can use the
lsof command. By default, without any arguments,
lsof is going to list all open files that belong to every open process.
lsof without any arguments just once to fully realize how much stuff is actually happening behind the scenes on your machine. When I ran
time on my laptop, it took nearly 10 seconds to dump out everything. WOW.
Fortunately, we can pass in a few additional arguments and cut through the clutter to figure out which process is listening on a port:
$ sudo lsof -itcp:4000
lsof will return the process that is current listening on port
sudo is because we may not know which user account on the system may be holding the port.
Similar to top, the process ID is listed under the
Try it out, replace the port number with one that you know you have a process listening on.
If you’re a command-line junky like myself, you are probably wondering why
ps didn’t make the list.
Between you and me, I think
ps is absolutely amazing. So much so, that I think it deserves an in depth article all it’s own :)