1. Overview
The Linux Operating system generates a PID for each process. In this quick tutorial, let’s explore how to get the process name by a given PID.
2. Introduction to the Problem
As usual, let’s understand the problem by an example.
First, let’s create a simple shell script to simulate a long-running process:
$ cat long-running.sh
#!/bin/bash
echo "PID of $0: $$"
echo "Parameter: $1"
watch -n 300 date > /dev/null
As we can see, we first print the PID of the current script by reading the special variable $$. Then, we tell the watch command to execute the date command every 300 seconds and discard the output.
In this way, we can know its PID when we start the script. Further, it runs as a “long-running” process:
$ ./long-running.sh PARAM
PID of ./long-running.sh: 407203
parameter: PARAM
Now, assuming we only know this PID, we would like to figure out which process is running with this PID.
Of course, our expected result is the long-running.sh script. Next, let’s see how to find the process.
3. Using the ps Command
The ps command is the standard tool to check current processes’ status in the Linux command line.
Further, we can pass the -p
$ ps -p 407203
PID TTY TIME CMD
407203 pts/3 00:00:00 long-running.sh
As the output above shows, we’ve seen the expected process name in the CMD column. We can also adjust the ps command’s -o option to ask ps to output only required information.
For example, we can pass “-o comm” to the ps command to get the name of the program only:
$ ps -p 407203 -o comm
COMMAND
long-running.sh
If we want to know the entire command line that was used to start the given process, we can pass “-o command” to ps:
$ ps -p 407203 -o command
COMMAND
/bin/bash ./long-running.sh PARAM
As the output shows, this time, the ps command reports the complete command, including parameters used to start the process.
Sometimes, we want to suppress the column header, for example, “COMMAND” in the output above, so that we can easily pass the result to other programs to do further processing.
To suppress the header from the ps output, we can simply add the “=” character after the -o ColumnName option:
$ ps -p 407203 -o command=
/bin/bash ./long-running.sh PARAM
4. Reading Files Under the /proc/ Directory
The /proc directory is present on all Linux distributions. This directory is a virtual file system. The /proc directory contains details about processes and other system information such as kernel, memory usage, CPU data, and configuration parameters. The operating system mounts /proc at boot.
Each process has a subdirectory under the /proc directory named with its PID. For example, if we want to check the information of the process 407203, we can enter the /proc/407203 directory. There are many “files” under each /proc/
$ ls /proc/407203
arch_status cwd@ maps pagemap stat
attr/ environ mem personality statm
...
exe@ ...
cmdline io ns/ sessionid timers
comm ...
We can read three files to gain the name or the command line of the process: comm, exe, and cmdline. Next, let’s see them in action.
To get the program name of a process, we can read the comm file:
$ cat /proc/407203/comm
long-running.sh
The exe file is a symbolic link. It links to the real command file to start the process:
$ ls -l /proc/407203/exe
lrwxrwxrwx 1 kent kent 0 Apr 26 09:20 /proc/407203/exe -> /usr/bin/bash
As our process is a shell script, which is always started by the shell, the exe file will merely link to the shell command, which is /usr/bin/bash in this case. However, if our process is started by a regular program, the exe file will point to the executable:
$ ls -l /proc/437301/exe
lrwxrwxrwx 1 kent kent 0 Apr 26 09:17 /proc/437301/exe -> /usr/bin/vim
The example above shows a vim process.
However, if we would like to know the complete command that started the process along with its parameters, we can check the cmdline file:
$ cat /proc/407203/cmdline
/bin/bash./long-running.shPARAM
As the output above shows, the shell command, script name, and the script parameter are printed, but they are joined together without separators.
Actually, the output is separated by null characters. We can see them if we pass the -A option (display all) to the cat command:
$ cat -A /proc/407203/cmdline
/bin/bash^@./long-running.sh^@PARAM^@
This time, we can see that the null characters are represented as ‘*^@*‘.
We can use the tr command to reformat the output. For example, we can replace all null characters with spaces:
$ cat /proc/407203/cmdline | tr '\0' ' '
/bin/bash ./long-running.sh PARAM
5. Conclusion
In this quick article, we’ve explored how to get the name and the command line of a given PID in the Linux command line.
The ps -p