They do not.
So strictly speaking a question asking why they do is unanswerable, it taking a falsehood as its premise.
They show the cmd and the ucmd columns, two different pieces of information. Unfortunately, both the GNU ps program and the FreeBSD ps program make things quite confusing here.
Kernels such as Linux and the kernels of the BSDs provide four (relevant) pieces of information about a process, via files in /proc and sysctl():
- its program image short name, a.k.a. the short name used for process accounting;
- its argument strings, initialized by
execve() and modifiable at runtime;
- its environment strings, initialized by
execve() and modifiable at runtime; and
- the full pathname of its executable program image file.
The argument strings and environment strings are modifiable at runtime in ways that I covered in https://unix.stackexchange.com/a/438007/5132 and https://unix.stackexchange.com/a/432681/5132 . Linux also permits modifying the process accounting name.
GNU Screen has modified its argument strings, so that the first one reads "SCREEN", but not its process accounting name, which remains as "screen".
There are just two columns for displaying these four pieces of information in ps. In the FreeBSD ps, the columns comprise this information as follows:
- The column named by
command and args comprises the argument strings, plus the environment strings if the e option is used, plus the accounting name in square brackets if it does not match the first of the argument strings; all prefixed with a tree diagram if the d option is used and it is the last column.
- The column named by
ucomm and comm comprises the process accounting name.
The GNU ps adds cmd as an alias for the former and ucmd as an alias for the latter. It puts the tree diagram and environment strings in both columns, and always puts the tree diagram in even if the column is not the last column.
With GNU ps, the -f option (not to be confused with the f option) in the -Af in the question is simply a shorthand for specifying a different set of columns for ps to print. The default set of columns includes ucmd. The set used when the -f option is used includes cmd instead.
The manual for BSD ps lays this out explicitly, giving the exact columns selected by its -j, -l, -u, and -v shorthands. The manual for GNU ps mentions "full format", "jobs format", "long format", and "user format" but does not explicitly list which set of columns each one is.
To further the confusion, both the GNU ps and the FreeBSD ps do not use the column names used on the command line, in the column headings given in their outputs. So one often cannot tell from the column heading alone which column is actually being displayed.
- FreeBSD
ps labels the accounting name column either UCOMM or COMMAND, but also labels the argument strings column COMMAND.
- GNU
ps labels the argument strings column either CMD or COMMAND, but also labels the accounting name column either CMD or COMMAND.
(Laurent Bercot's s6-ps, for comparison, has just comm, args, and env, with fixed and distinct header labels COMM, COMMAND, and ENVIRONMENT, giving just the first three of the four pieces of information from the kernel directly, without combining them.)
- Laurent Bercot (2014).
s6-ps. s6-linux-utils. Software.
argvarray? The change is internal to the screen program, so how can it be visible tops? – Tim Jan 03 '19 at 21:17hexdump -C /proc/self/cmdline– Michael Homer Jan 03 '19 at 21:18/proc/self/cmdlineeffectively reads the argv array from inside the program each time. The kernel does not keep a second copy of the arguments, so there is nothing to update. It is very similar to usinggdbto debug the program and view the current contents of the array. – sourcejedi Jan 04 '19 at 17:17./sleep.py, does python interpreter modify the value in argv[0] to be/usr/bin/python3? See https://unix.stackexchange.com/questions/498244/how-is-a-windows-executable-file-run-via-wine – Tim Feb 02 '19 at 04:23./sleep.py, not/usr/bin/python3 ./sleep.py– Tim Feb 02 '19 at 04:35ps -fuses the process's ARGV and sees changes to it, whilepssees the executable name which itself is unchanged." Is the executable name stored somewhere (the first argument toexecve()?), how doespsfind it out? – Tim Feb 02 '19 at 04:39./sleep.py, there will be two calls toexecve(). The first call treats the script as an executable and fails, and the second call toexecve()actually with the same arguments as when running a command/usr/bin/python3 ./sleep.py– Tim Feb 02 '19 at 04:42commandvsargsoutput format specifier. – DouglasDD Jul 30 '23 at 11:41