1

Why does the following two commands of ps give different CMD field? It matters because screen and SCREEN are different: the first is client and the second is server. Thanks.

$ ps -A | grep -i screen
 3341 ?        00:00:00 screen
 3875 ?        00:00:00 screen
27525 ?        00:00:00 screen
$ ps -Af | grep -i screen
testme    3341     1  0  2018 ?        00:00:00 SCREEN -S testme
testme    3875     1  0  2018 ?        00:00:00 SCREEN -S tm
t        27525     1  0  2018 ?        00:00:00 SCREEN -S test

SCREEN is not a program, and then why is it showed in ps?

$ SCREEN
SCREEN: command not found
Tim
  • 101,790

3 Answers3

7

screen renames its main (server) process SCREEN to distinguish it from later clients.

This is very obliquely mentioned once in the man page:

Note that this command only affects debugging output from the main "SCREEN" process correctly. Debug output from attacher processes can only be turned off once and forever.

but, oddly, not explicitly mentioned anywhere I can see.

ps and ps -f display different things for CMD: the executable name (ps, the "command" format specifier) and the reconstructed command line (ps -f, the "args" format specifier). The latter uses the process's ARGV and sees changes to it, while the executable name itself is unchanged.

Michael Homer
  • 76,565
  • Thanks. What is the API function which allows a process to change its name? – Tim Jan 03 '19 at 21:11
  • There/s no function, you just update the argument array. – Michael Homer Jan 03 '19 at 21:12
  • Do you mean the screen program changes the values of the elements in its argv array? The change is internal to the screen program, so how can it be visible to ps? – Tim Jan 03 '19 at 21:17
  • hexdump -C /proc/self/cmdline – Michael Homer Jan 03 '19 at 21:18
  • Does the linux kernel read and update the values in argv array in /proc/self/cmdline, when a program changes them internally? – Tim Jan 03 '19 at 21:27
  • It would seem so. – Michael Homer Jan 03 '19 at 21:28
  • @Tim Reading from /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 using gdb to debug the program and view the current contents of the array. – sourcejedi Jan 04 '19 at 17:17
  • When running a python script in shell as command ./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
  • It already says that, so it doesn't need to modify it. – Michael Homer Feb 02 '19 at 04:29
  • What do you mean by "It already says that"? The command to run the script is ./sleep.py, not /usr/bin/python3 ./sleep.py – Tim Feb 02 '19 at 04:35
  • " ps -f uses the process's ARGV and sees changes to it, while ps sees the executable name which itself is unchanged." Is the executable name stored somewhere (the first argument to execve()?), how does ps find it out? – Tim Feb 02 '19 at 04:39
  • Am I correct that when running ./sleep.py, there will be two calls to execve(). The first call treats the script as an executable and fails, and the second call to execve() actually with the same arguments as when running a command /usr/bin/python3 ./sleep.py – Tim Feb 02 '19 at 04:42
  • @Tim you’ve asked similar questions before, the answers to which explained how scripts are run — see What is the actual command executed when running a script with a shebang as its name with same arguments? for example. – Stephen Kitt Feb 02 '19 at 19:44
  • Similarly bash login shells will show as "bash" or "-bash" depending on the ps command vs args output format specifier. – DouglasDD Jul 30 '23 at 11:41
4

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.
JdeBP
  • 68,745
  • 1
    I'm not aware that GNU has a ps command. I think you're actually referring to the procps/procps-ng implementation. – Stéphane Chazelas Jan 04 '19 at 09:23
  • It's the GNU-licensed one, as distinguished from the one with the FreeBSD licence. The situation is already complex to explain. I am reluctant to make it further complicated by adding an irrelevant tangent about software authorship and licences, or cluttering it with long winded descriptions. This answer is about the columns. Short "GNU" and "FreeBSD" attributions are clear enough, especially since the questioner already knows what ps xe is using, any clarification of which point belongs in the question. – JdeBP Jan 04 '19 at 09:57
  • busybox is also licensed under the GNU GPL, I don't see how the license has any relevance on the implementation here. Why don't you call is procps ps? GNU screen is (now back) in the GNU project. procps is not. – Stéphane Chazelas Jan 04 '19 at 09:59
  • Thanks. Can you be more specific about "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()"? Which file in /proc and which arguments to sysctl() provide each of the four pieces of information? – Tim Jan 04 '19 at 14:18
  • The "GNU"/"BSD" attribution is the terminology from the manual page of the very GNU ps program under discussion M. Chazelas. Take it up with its authors. – JdeBP Jan 04 '19 at 16:08
  • @JdeBP where? in this version? https://gitlab.com/procps-ng/procps/blob/master/ps/ps.1 – sourcejedi Jan 04 '19 at 16:47
  • There are 9 attributive uses of "BSD" in that document. As I said, take it up with the question (whose lack of identification of the ps program you have not queried at all) and with the authors of the manual, and stop mucking about here. – JdeBP Jan 04 '19 at 17:26
  • 1
    @JdeBP, all I see in that man page is references to GNU style of options (--option). Again, procps ps is not GNU ps, it's not maintained by the FSF, it's not part of the GNU project. Calling it GNU ps is as wrong as calling it Microsoft ps just because it does run on PCs with a Windows key on the keyboard. – Stéphane Chazelas Jan 04 '19 at 17:47
  • @ JdeBP Is "program image short name, a.k.a. the short name used for process accounting" modifiable at runtime? – Tim Jan 04 '19 at 23:19
  • "its environment strings, initialized by execve() and modifiable at runtime", I found it is not modifiable at runtime. See man proc which says "If, after an execve(2), the process modifies its environment (e.g., by calling functions such as putenv(3) or modifying the environ(7) variable directly), this file will not reflect those changes." – Tim Jan 04 '19 at 23:31
2

ps -A uses the default format, which shows the pid, terminal, cumulated CPU time, and the executable name (ucmd). The executable name is not modifiable, and reflects exactly the name of the executable used.

ps -Af uses the full format, which among other fields, shows the full command with arguments (comm, or args). The full command is modifiable, and as explained in Michael Homer’s answer, screen modifies it to show whether the process is a client or a server.

To find screen processes and determine their purpose, use

ps -fC screen

This shows the full details of processes whose executable name matches screen.

Stephen Kitt
  • 434,908