2

How can an original command issued at the command line be acquired without using proc or any other non standard tool?

When printing a process list using ps, the arguments passed in to initiate the command are shown without quotes, which is not how the original command was issued. It also appears that no combination of ps options can achieve this either.

After searching for quite some time and even reviewing the hard to find ps source code, there was no simple answer. Currently there are other posts mentioning the same issue but are either unanswered or the solutions proposed are not satisfactory. The ps source code can probably be edited to achieve the necessary result, but this approach is not preferred as ps is actually a non standard package that was coded significantly differently for every operating system it was on. For example the source code for ps on MacOS is drastically different than the source code for ps on ubuntu.

1 Answers1

2

There is no portable way to get an unambiguous representation of the command line of another process. You didn't find the answer you're looking for because it's impossible. You either need to cope with an ambiguous representation, or to use a different method depending on which OS your code is running on, or to find someone who's done that work for you.

The POSIX specification of ps does not specify exactly how the args field is formatted, merely that it contains “the command with all its arguments as a string” and that it may be truncated. In practice, all the implementations I've seen concatenate the arguments with a space in between. That's the best you can do with POSIX.

If you want an unambiguous representation of a process's command line argument, you can find it in /proc/PID/cmdline on Linux and other Unix variants with a Solaris-like proc filesystem (so not BSD systems such as macOS). The arguments are separated by null bytes, which can't appear in an argument, so the representation is unambiguous. I don't think there's a way to get this information with the Linux procps ps utility, and even if there was it would be specific to Linux so it wouldn't be any more portable (less portable, in fact, since looking inside /proc works even on Linux kernels that have a different ps utility such as the one from BusyBox).

I don't know how to get an unambiguous representation of the command line arguments on macOS.

I know of one program that's done the non-portable part: the Python library psutil. I can confirm that it lets you obtain an unambiguous representation of the command line of a process on Linux. It should also work on macOS since the documentation doesn't mention any restriction, but I haven't tested.

python3 -c 'import os, psutil; print(psutil.Process(os.getpid()).cmdline())'
  • I was afraid of this. I knew it was impossible, but didn't want to accept it. I have confirmed it by reading the ps source code and can see clearly the flaw that doesn't account for the null byte that separates the flags. Since ps IS the portable solution for this, then that confirms no portable solution. I still had hope, which is all you could have when you are stuck with nothing. I believe the only solution now is to create my own portable solution, either by recompiling ps for the top 3 operating systems or just making a hack script that extracts the pieces of information from each os. – Michael Marcus Feb 12 '20 at 21:54
  • @MichaelMarcus If your platform has Python, someone has already done this script that extracts the pieces of information. – Gilles 'SO- stop being evil' Feb 13 '20 at 11:33