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.
argv
array? 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/cmdline
effectively 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 usinggdb
to 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 -f
uses the process's ARGV and sees changes to it, whileps
sees the executable name which itself is unchanged." Is the executable name stored somewhere (the first argument toexecve()
?), how doesps
find 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:42command
vsargs
output format specifier. – DouglasDD Jul 30 '23 at 11:41