This has nothing to do with foreground and background processes; it only has to do with the currently running process. When the kernel has to answer the question “What does /proc/self point to?”, it simply picks the currently-scheduled pid, i.e. the currently running process (on the current logical CPU). The effect is that /proc/self always points to the asking program's pid; if you run
ls -l /proc/self
you'll see ls's pid, if you write code which uses /proc/self that code will see its own pid, etc.
This has nothing to do with foreground and background processes; it only has to do with the currently running process. When the kernel has to answer the question “What does /proc/self point to?”, it simply picks the currently-scheduled pid, i.e. the currently running process (on the current logical CPU). The effect is that /proc/self always points to the asking program's pid; if you run
ls -l /proc/self
you'll see ls's pid, if you write code which uses /proc/self that code will see its own pid, etc.
The one that accesses the symlink (calls readlink() on it, or open() on a path through it). It would be running on the CPU at the time, but that's not relevant. A multiprocessor system could have several processes on the CPU simultaneously.
Foreground and background processes are mostly a shell construct, and there's no unique foreground process either, since all shell sessions on the system will have one.
use strings
$ cat /proc/self/cmdline | strings -1
cat
/proc/self/cmdline
The /proc/PID/cmdline is always separated by NUL characters.
To understand spaces, execute this command:
cat -v /proc/self/cmdline "a b" "c d e"
EDIT: If you really see spaces where there shouldn't be any, perhaps your executable (intentionally or inadvertently) writes to argv[], or is using setproctitle()?
When the process is started by the kernel, cmdline is NUL-separated, and the kernel code simply copies the range of memory where argv[] was at process startup into the output buffer when you read /proc/PID/cmdline.
The detail which you are extracting from /proc/self/status is found in /proc/self/comm (without scripting).
For the intended question: to determine which processes are interpreted and which are native, you cannot do this without knowing which processes are intended to be interpreters. After all, any process can rename itself via an exec call, using whatever it likes to the resulting process's argument list. You could guess by comparing /proc/self/exe (which points to the executable) to the argument list, but that would only be a guess, since there are examples where a non-interpreter renames its descendants just to make their use more apparent.
Further reading:
- Getting Process Invocations: The Hard Way
- The /proc filesystem
- Howto change a UNIX process and child process name by modifying argv[0]
It appears processes get Names in
</proc/self/status |grep '^Name'
and the name appears to be the basename of the real zeroth argument.
(I'll keep the question here in case someone provides a better answer).