How do I get the path of a process in Unix / Linux

LinuxUnixProcessPathEnvironment

Linux Problem Overview


In Windows environment there is an API to obtain the path which is running a process. Is there something similar in Unix / Linux?

Or is there some other way to do that in these environments?

Linux Solutions


Solution 1 - Linux

On Linux, the symlink /proc/<pid>/exe has the path of the executable. Use the command readlink -f /proc/<pid>/exe to get the value.

On AIX, this file does not exist. You could compare cksum <actual path to binary> and cksum /proc/<pid>/object/a.out.

Solution 2 - Linux

You can find the exe easily by these ways, just try it yourself.

  • ll /proc/<PID>/exe
  • pwdx <PID>
  • lsof -p <PID> | grep cwd

Solution 3 - Linux

A little bit late, but all the answers were specific to linux.

If you need also unix, then you need this:

char * getExecPath (char * path,size_t dest_len, char * argv0)
{
    char * baseName = NULL;
    char * systemPath = NULL;
    char * candidateDir = NULL;

    /* the easiest case: we are in linux */
    size_t buff_len;
    if (buff_len = readlink ("/proc/self/exe", path, dest_len - 1) != -1)
    {
        path [buff_len] = '\0';
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Ups... not in linux, no  guarantee */

    /* check if we have something like execve("foobar", NULL, NULL) */
    if (argv0 == NULL)
    {
        /* we surrender and give current path instead */
        if (getcwd (path, dest_len) == NULL) return NULL;
        strcat  (path, "/");
        return path;
    }


    /* argv[0] */
    /* if dest_len < PATH_MAX may cause buffer overflow */
    if ((realpath (argv0, path)) && (!access (path, F_OK)))
    {
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Current path */
    baseName = basename (argv0);
    if (getcwd (path, dest_len - strlen (baseName) - 1) == NULL)
        return NULL;

    strcat (path, "/");
    strcat (path, baseName);
    if (access (path, F_OK) == 0)
    {
        dirname (path);
        strcat  (path, "/");
        return path;
    }

    /* Try the PATH. */
    systemPath = getenv ("PATH");
    if (systemPath != NULL)
    {
        dest_len--;
        systemPath = strdup (systemPath);
        for (candidateDir = strtok (systemPath, ":"); candidateDir != NULL; candidateDir = strtok (NULL, ":"))
        {
            strncpy (path, candidateDir, dest_len);
            strncat (path, "/", dest_len);
            strncat (path, baseName, dest_len);

            if (access(path, F_OK) == 0)
            {
                free (systemPath);
                dirname (path);
                strcat  (path, "/");
                return path;
            }
        }
        free(systemPath);
        dest_len++;
    }

    /* again someone has use execve: we dont knowe the executable name; we surrender and give instead current path */
    if (getcwd (path, dest_len - 1) == NULL) return NULL;
    strcat  (path, "/");
    return path;
}

EDITED: Fixed the bug reported by Mark lakata.

Solution 4 - Linux

I use:

ps -ef | grep 786

Replace 786 with your PID or process name.

Solution 5 - Linux

pwdx <process id>

This command will fetch the process path from where it is executing.

Solution 6 - Linux

The below command search for the name of the process in the running process list,and redirect the pid to pwdx command to find the location of the process.

ps -ef | grep "abc" |grep -v grep| awk '{print $2}' | xargs pwdx

Replace "abc" with your specific pattern.

Alternatively, if you could configure it as a function in .bashrc, you may find in handy to use if you need this to be used frequently.

ps1() { ps -ef | grep "$1" |grep -v grep| awk '{print $2}' | xargs pwdx; }

For eg:

[admin@myserver:/home2/Avro/AvroGen]$ ps1 nifi

18404: /home2/Avro/NIFI

Hope this helps someone sometime.....

Solution 7 - Linux

In Linux every process has its own folder in /proc. So you could use getpid() to get the pid of the running process and then join it with the path /proc to get the folder you hopefully need.

Here's a short example in Python:

import os
print os.path.join('/proc', str(os.getpid()))

Here's the example in ANSI C as well:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


int
main(int argc, char **argv)
{
    pid_t pid = getpid();

    fprintf(stdout, "Path to current process: '/proc/%d/'\n", (int)pid);

    return EXIT_SUCCESS;
}

Compile it with:

gcc -Wall -Werror -g -ansi -pedantic process_path.c -oprocess_path 

Solution 8 - Linux

There's no "guaranteed to work anywhere" method.

Step 1 is to check argv[0], if the program was started by its full path, this would (usually) have the full path. If it was started by a relative path, the same holds (though this requires getting teh current working directory, using getcwd().

Step 2, if none of the above holds, is to get the name of the program, then get the name of the program from argv[0], then get the user's PATH from the environment and go through that to see if there's a suitable executable binary with the same name.

Note that argv[0] is set by the process that execs the program, so it is not 100% reliable.

Solution 9 - Linux

thanks : Kiwy
with AIX:

getPathByPid()
{
	if [[ -e /proc/$1/object/a.out ]]; then
		inode=`ls -i /proc/$1/object/a.out 2>/dev/null | awk '{print $1}'`
		if [[ $? -eq 0 ]]; then
			strnode=${inode}"$"
			strNum=`ls -li /proc/$1/object/ 2>/dev/null | grep $strnode | awk '{print $NF}' | grep "[0-9]\{1,\}\.[0-9]\{1,\}\."`
			if [[ $? -eq 0 ]]; then
				# jfs2.10.6.5869
				n1=`echo $strNum|awk -F"." '{print $2}'`
				n2=`echo $strNum|awk -F"." '{print $3}'`
				# brw-rw----    1 root     system       10,  6 Aug 23 2013  hd9var
				strexp="^b.*"$n1,"[[:space:]]\{1,\}"$n2"[[:space:]]\{1,\}.*$"	# "^b.*10, \{1,\}5 \{1,\}.*$"
				strdf=`ls -l /dev/ | grep $strexp | awk '{print $NF}'`
				if [[ $? -eq 0 ]]; then
					strMpath=`df | grep $strdf | awk '{print $NF}'`
					if [[ $? -eq 0 ]]; then
						find $strMpath -inum $inode 2>/dev/null
						if [[ $? -eq 0 ]]; then
							return 0
						fi
					fi
				fi
			fi
		fi
	fi
	return 1
}

Solution 10 - Linux

You can also get the path on GNU/Linux with (not thoroughly tested):

char file[32];
char buf[64];
pid_t pid = getpid();
sprintf(file, "/proc/%i/cmdline", pid);
FILE *f = fopen(file, "r");
fgets(buf, 64, f);
fclose(f);

If you want the directory of the executable for perhaps changing the working directory to the process's directory (for media/data/etc), you need to drop everything after the last /:

*strrchr(buf, '/') = '\0';
/*chdir(buf);*/

Solution 11 - Linux

Find the path to a process name

#!/bin/bash
# @author Lukas Gottschall
PID=`ps aux | grep precessname | grep -v grep | awk '{ print $2 }'`
PATH=`ls -ald --color=never /proc/$PID/exe | awk '{ print $10 }'`
echo $PATH

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlsalamonView Question on Stackoverflow
Solution 1 - LinuxjpalecekView Answer on Stackoverflow
Solution 2 - LinuxhahakubileView Answer on Stackoverflow
Solution 3 - LinuxHiperionView Answer on Stackoverflow
Solution 4 - LinuxUserView Answer on Stackoverflow
Solution 5 - LinuxgobiView Answer on Stackoverflow
Solution 6 - LinuxArunView Answer on Stackoverflow
Solution 7 - LinuxhyperboreeanView Answer on Stackoverflow
Solution 8 - LinuxVatineView Answer on Stackoverflow
Solution 9 - LinuxzirongView Answer on Stackoverflow
Solution 10 - LinuxJimmio92View Answer on Stackoverflow
Solution 11 - LinuxDwDView Answer on Stackoverflow