5

I'm writing a script which will use the filename of running processes. However, I'm unable to determine the full executable name of some processes.

Initially, I decided to query the Name entry in /proc/PID/status (or the second field in /proc/PID/stat). However, according to the manpage, that field is always truncated to 15 characters, but I need the full name to avoid conflict/confusion.

An answer of this question suggests to use /proc/PID/cmdline, but there are problems too. Some programs (e.g. chromium, electron) do stupid/smart things to the value in /proc/PID/cmdline so I can't just split the data there by NULL and directly get the program name as suggested in the manpage - they fill in a lot of things to the original argv[0] field and separate them by space, and I don't think merely splitting by space is a good choice because the path/filename may contain spaces.

This is even more complicated when I find out that some scripts (e.g. python scripts) are in the form /usr/bin/python /path/to/script while some are in the form /path/to/script. Though this is much easier to deal with as long as I have that field (without jams as above) and manually check and split.

Any ideas how to get the full program name/filename? It doesn't matter if the name contains the full path or not because that can be easily dealt with (as far as I can see now).

  • What about looking up the target of /proc/PID/exe ? – user60039 May 27 '17 at 14:45
  • @user60039 For general cases, there is a problem with symlinks. (See my comment to ilkkachu's answer.) – renyuneyun May 28 '17 at 17:09
4

/proc/$PID/exe seems to be what you're looking for: (proc(5)

/proc/[pid]/exe
Under Linux 2.2 and later, this file is a symbolic link containing the actual pathname of the executed command. This symbolic link can be dereferenced normally; attempting to open it will open the executable.

So, simply:

$ /bin/cat & readlink /proc/$!/exe
/bin/cat

It actually follows renames on the executable file:

/tmp$ cp /bin/cat . ; ./cat & mv cat dog ; readlink /proc/$!/exe
/tmp/dog
  • For most cases it works well, but there is a problem with symlinks (if I identify the problem correctly). If the original command is a symlink to another file, then /proc/[pid]/exe would dereference the symlink and point to the actual file. Though for my case this behaviour won't harm. – renyuneyun May 28 '17 at 17:01
  • @renyuneyun, hmm, yes, for the same reason my example of moving the executable after starting it works like it does, the exe entry tracks the actual file. cmdline would have the name the program received as argv[0] on startup, but IIRC that can be overwritten... I'm not sure but it comes to mind that to get a copy of the argv as it was when the process exec'd, you'd need to trace it. – ilkkachu May 30 '17 at 12:43
  • Yes, cmdline can be overwritten. This is the reason I didn't want to use it in the first place (but sadly I still need to use it when exe points to the interpretor, e.g. python). What do you mean by "you'd need to trace it"? In the original program (or by modifying kernel)? – renyuneyun May 30 '17 at 14:31
  • @renyuneyun, trace as in with a debugger to peek into the argv values before they're changed, or run under strace to see the exec syscall. – ilkkachu May 30 '17 at 15:21
  • Aha, it doesn't seem to fit my needs. But anyway, I learned something new :) – renyuneyun May 31 '17 at 11:38
-2

On a platform with a standard procfs with procfs-2 support, you get the result via:

ls -l /proc/<pid>/path/a.out

The file a.out is a symlink to the absolute path of the binary.

Note that the question did not mention Linux and for this reason, it makes sense to give information on how this feature works on the procfs original implementation from the procfs inventor Roger Faulkner.

  • Well, actually, the question title explicitly mentions Linux. But you're right in that it's not tagged or mentioned in the text. – ilkkachu Jun 12 '18 at 12:49
  • Correct, there is no linux tag and even if there was one, my answer could help others to understand how it works on other platforms. If you look at various GNU programs, you will see that information on /procfs is widely missing and software that claims to be portable is frequently not when it tries to use /procfs. – schily Jun 12 '18 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.