25

I know that I can get the PID for a process by using ps, but how to a find the full path of that process?

ymn
  • 2,175
  • 2
  • 21
  • 39
Kramer
  • 927
  • 2
  • 13
  • 30
  • http://superuser.com/questions/103309/how-can-i-know-the-absolute-path-of-a-running-process – Iswanto San Feb 11 '13 at 04:34
  • possible duplicate of [Get real path of application from pid?](http://stackoverflow.com/questions/7511864/get-real-path-of-application-from-pid) – talha2k Feb 11 '13 at 04:39

5 Answers5

22

OS X has the libproc library, which can be used to gather different process informations. In order to find the absolute path for a given PID, the following code can be used:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libproc.h>

int main (int argc, char* argv[])
{
    pid_t pid; int ret;
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];

    if ( argc > 1 ) {
        pid = (pid_t) atoi(argv[1]);
        ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
        if ( ret <= 0 ) {
            fprintf(stderr, "PID %d: proc_pidpath ();\n", pid);
            fprintf(stderr, "    %s\n", strerror(errno));
        } else {
            printf("proc %d: %s\n", pid, pathbuf);
        }
    }

    return 0;
}

Example to compile and run (above code is stored in pathfind.c, 32291 is the pid of the process I'm trying to find path info for):

$ cc pathfind.c -o pathfind
$ ./pathfind 32291
proc 32291: /some/path/your-binary-app

Refer to this blog post: http://astojanov.wordpress.com/2011/11/16/mac-os-x-resolve-absolute-path-using-process-pid/

DustinB
  • 11,037
  • 5
  • 46
  • 54
talha2k
  • 24,937
  • 4
  • 62
  • 81
  • 1
    I've touched up this code such that it takes a PID as an argument and prints the absolute path to that process' executable : https://gist.github.com/bukzor-sentryio/f74da9b1799c2f239476941774cf5552 – bukzor Jan 02 '23 at 20:20
14

One solution can be using which:

which `ps -o comm= -p $PID`

Where $PID is pid of process you want to check. Tested on OS X 10.8.2.

tomis
  • 1,884
  • 1
  • 15
  • 28
  • 2
    Tested on 10.7.5 as well... brilliant. – Floris Feb 11 '13 at 12:11
  • 1
    It seems to return relative paths sometimes though. Here is the test I made: `$> which \`ps -o comm= -p 81233\` => ./ft_minishell2`, I mean, it's not a fullpath as in absolute path. Don't know if that was the initial thinking behind the question. This is Mavericks. – conradkleinespel Mar 02 '14 at 21:17
  • 15
    This may not be accurate if you have an executable with the same name in different locations, esp one that is not on your path. "which" searches your PATH env variable for the give executable, but that may not necessarily be the one showing up in process list. @conradk The reason it is 'relative' is because it is in your current directory. – DustinB Dec 30 '14 at 15:49
  • Anyway to not have a line break with absolute path result? (tested with 10.12.6) – Michael Oct 25 '17 at 18:26
  • @Michael Probably best to remove this via ```sed``` if tou want to use that in script. – tomis Oct 26 '17 at 10:22
  • 1
    Seems to work very well in macOS 11.4 Big Sur! – Altimac Jul 05 '21 at 13:19
  • Returns nothing in Ventura – Alvaro Lourenço Mar 23 '23 at 12:49
  • In my case the precise reason I want to do that is to make sure if the version of a program on the path is the same as the one in a runnin process... – Att Righ Jun 05 '23 at 15:59
1

All the answers involving ps are insufficient, because the ps command on MacOS can only show the full path of an executable if it was launched using its full path. If the process was launched using a relative path or just the filename that was then looked up in PATH, the ps command will not show the full path.

The lsof command can be used to display full path names of running processes on MacOS regardless how they were launched, as follows:

lsof -d txt

The last column of the output shows the full path of each executable.

If you wanted to see just the full path of a specific process with PID 123:

lsof -a -d txt -p 123

The -a parameter is important in this case, to force an "AND" matching of the specified criteria.

If you wanted to see the full path by process name, you can use this:

lsof -a -d txt -c python

This will give you the full path of all running processes whose executable name starts with "python". This means you might also get "python2" and "python3" processes in this list, which is often what you want.

However, if you wanted an exact match on process name, the -c command also supports regular expressions, so you could use an anchored regex like this:

lsof -a -d txt -c /^python$/

This will give you only processes named python and nothing else.

One final wrinkle is that Apple sometimes likes to capitalize the names of executables that come bundled with MacOS.

For example, the Python executable bundled with MacOS is actually named Python (with a capital P), even if you launched it from the command line as python (lowercase P).

To cope with this, the -c argument also allows case-insensitive matching by appending the i flag after the regex, as follows:

lsof -a -d txt -c /^python$/i

This will give you the full paths of all running processes named python or Python, regardless of case.

grnch
  • 131
  • 4
  • This isn't answering the OP's question. `lsof` lists open files, not files that represent processes. See e.g. https://en.wikipedia.org/wiki/Procfs – Bill Horvath Feb 01 '23 at 16:23
  • @BillHorvath, have you tried the commands above on MacOS? The OP asked for the full paths of executables for running process, which the above `lsof` commands absolutely provide. We're not listing all the open files here, the trick is in the `-d txt` switch which lists only the "text segments" (aka "executable code") that have been mapped into memory for each process, which directly reveals the path of the executable where the running process came from. P.S. procfs does not exist on Mac OS. – grnch Feb 01 '23 at 20:21
-2

A more portable and modern version of @tomis's answer:

command -v "$(ps -o comm= -p $PID)"

command -v replaces which and is more portable.

Backticks are replaced by $(cmds)

And another alternative that depends on realpath from the GNU CoreUtils:

realpath /proc/$PID/exe
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
-8

Try this:

sudo ls -l /proc/$(ps -e | grep $PROCESS_NAME | awk '{print $1}')/exe

where $PROCESS_NAME is name of process you want to check.

ymn
  • 2,175
  • 2
  • 21
  • 39
  • Do you heard about `osxfuse` -- The repository filesystems contains source code for several exciting and useful file systems for you to browse, compile, and build upon, such as sshfs, procfs, AccessibilityFS, etc. – ymn Feb 11 '13 at 05:48
  • 2
    I have heard about that (and using it) but it's not natively there... Many users does not have this installed. – tomis Feb 11 '13 at 05:51