About the ps Command's Options
Contents
- About the
ps
Command - The Origin of
ps
Option Styles ps
Option Categories- Which Processes Should
ps
Display? - Selecting Fields
- Formatting
ps
Output - Conclusion
About the ps
Command
The ps
command is the main administrative tool in Unix-family and
Linux systems to monitor processes. It has a vast number of options,
which historically have varied significantly across different systems,
even though the basic function of the command is the same. The primary
difference is that some versions of the ps
command use the customary
-
(dash or minus) to introduce options and some do not.
The origin of those differences lie in the 1980s split between AT&T’s commercial Unix (System III and System V) and Berkeley’s BSD distribution. Both were used by different Unix system vendors for their commercial offerings, which resulted in confusing inconsistencies for Unix system administrators who worked in mixed environments – a common situation in the 1980s and 1990s.
To quote the POSIX standard:
There is very little commonality between BSD and System V implementations of ps. Many options conflict or have subtly different usages.
The Origin of ps
Option Styles
The ps
(process status) command originally appeared in Unix 3rd
Edition alongside kill
as super-user only commands. They were
documented in the maintenance command section (section 8) of the
manual dated January 20, 1973.
This very early version of ps
had options and output that looked
quite different from later ps
versions. In late-1973 4th Edition
Unix, ps
moved to the command section (section 1) of the manual. It
had flags and produced output more in line with what a system
administrator today would recognize. By 1975, ps
had headers in its
output and the supported flags had settled on a
, k
, l
, and x
,
which (with the exception of the k
option) still have the same
meaning today.
While further editions of Research Unix did not document the use of
the dash for the options to ps
, they were actually supported in the
code of 6th and 7th Edition and the convention is acknowledged
elsewhere in the manuals. Other AT&T Unix versions like the
Programmer’s Workbench (PWB) or the AT&T-internal CB-Unix document the
use of a dash for the ps
command.
Flags vs. Options
Unix command arguments that are preceded by a minus (dash) are usually referred to as “options.” However,
ps
has tradtionally referred to them as “flags” and both of those terms are used in this post.The reason for indicating options with a special character is to differentiate them from filename arguments. This approach is based on the control-argument convention in the Multics operating system.
In the earliest versions of Unix, there briefly existed a alternative convention to use a
+
for options. Before GNU settled on--
for long options (ca. 1991), it used a+
too and that was phased out by about 1993.
The earliest BSD version that included its own ps
command was 3BSD
(1979). Prior to that, BSD was a collection of add-ons to AT&T’s
Research Unix. The 7th Edition of Research Unix was ported to the DEC
VAX by a group of engineers at Bell Labs different from the Research
Center team; this version was called Unix/32V and was the basis of
3BSD. Because 32V did not implement paging virtual memory, 3BSD
reimplemented the memory management system, which necessitated some
significant changes to the ps
command. It was 3BSD where the
commonly used option combination aux
originated.
In 1981, AT&T announced a supported version of Unix that combined
Research Unix and several other, internal Unix variants as System
III. That version not only used dashes for ps
flags, but also
changed the meaning of them. This is where the option idiom -ef
appeared. It’s unclear which of the System III antecedents (if any)
changed the flag meaning. Because so little of CB-Unix survives and
the other Unixes that contributed to System III did not change the
flags’ meanings, CB-Unix is a possible candidate for where this
evolution happened.
POSIX included ps
in the POSIX.2a User Portability Extension
(1992) and limited the options to a small subset of what was in
common use across System V and BSD systems at the time. The
XSI-extensions specified in the POSIX standard are based on the X/Open
standard XPG2 (1987) which was largely identical to System V
Release 3. Because of its origins, the POSIX-standard ps
uses dashes
and System V semantics for its flags.
The GNU implementation of ps
used in Linux supports the GNU-typical
long options preceded by two dashes in addition to the Unix and BSD
styles.
ps
Option Categories
The ps
command options roughly fall into these categories:
- Picking processes
- Selecting which information to show
- Formatting the output
Depending on the specific implementation of ps
, a small number of
options exist to, e.g., provide help or debug information. Especially
in older versions of the command, options existed to instruct ps
from which system image or memory file to read, which is used in
debugging system crashes.
The GNU version of ps
is implemented using the Linux /proc
filesystem (1992), which offers a standardized interface to commands
that otherwise would need direct access to kernel memory. This
abstraction was original work in 8th Edition Research Unix (1985),
which itself was based on BSD 4.1c. AT&T’s commercial System V
acquired /proc
with the SVR4 release (1989), which was licensed
for numerous other commercial Unix versions, most notably Sun’s
Solaris (1992).
Which Processes Should ps
Display?
The POSIX standard specifies that ps
without any options displays
the running processes owned by the user invoking the command; only
processes associated with the terminal on which ps
was invoked shall
be displayed. This is how GNU ps
operates – macOS however does not,
despite its certification as UNIX 03 compliant.
macOS
Owing to its BSD root, many of the macOS commands behave in line with their BSD counterparts. Starting with Mac OS X 10.5 (2007) and up to at least 12.0 Monterey (2021) macOS has been certified as a UNIX 03 operating system; it is compliant with a set of standards called the Single Unix Specification (SUSv3) based on POSIX and other related standards.
An environment variable
COMMAND_MODE
can be set tolegacy
to invoke Mac OS X 10.3 semantics for commands. When this variable is not set, SUSv3 complaint behavior can be expected.For the remainder of this post only POSIX and GNU
ps
will be considered.
The two most significant flags are to either select all users’ processes that are associated with a terminal or to select all processes regardless of whether or not they have a terminal.
-
-a
is the POSIX standard option to select processes associated with terminals. Both System V and BSD have a-a
anda
option, respectively, but with slightly different semantics. System V omits session leaders, while BSD does not. This is specified as optional in the standard; GNUps
follows the System V model. -
-A
shows all processes. It was chosen by POSIX as a compromise between the System V-e
and the BSDg
options. The POSIX XSI extension documents-e
as equivalent to-A
.
The BSD option x
to show processes without a terminal can trace its
origin back to the very first version of ps
. Any process that did
not have a “control typewriter” was listed with a terminal name of
x
.
-d
shows all processes except session leaders. In practice this means users’ interactive shells and parent dæmon processes will not show up.
Several options exist that take a comma- or space-separated list of IDs to select processes.
-p proclist
selects all processes from the proclist.
Older versions of BSD ps
allowed for specifying process IDs without
a flag. This is still supported in GNU and macOS ps
.
-
-t termlist
selects all process associated with the terminals in termlist. -U userlist
selects all processes with the real user given as an ID or name in userlist.-
-u userlist
selects all processes with the effective user given as an ID or name in userlist. This is a POSIX XSI extension and whether the output is user IDs or usernames depends on whether the-f
flag is used. This is in line with the System V behavior. -G grouplist
selects all process with the real group of the creator of the process given as an ID or name in grouplist.-g grouplist
logically should select process with the effective group ID, similar to how-u
works. GNUps
will in fact work this way as long as at least one item in the grouplist is non-numeric. The traditional System V definition is to select by process group list, POSIX defines it as selecting by session leader.
The unusual definition of the -g
flag shows the complexity of ps
options. GNU ps
solves this particular problem by supporting the
long options --User
, --user
, --Group
, and --group
.
Another difficulty is how different operating systems support process
groups and sessions. System V defines the -g
option as being used
for process groups. The session concept originated in POSIX as a an
extension of System V and BSD 4.3 process groups and made it into
SVR4. POSIX defines -g
as selecting by session leader instead of
process group, which is how GNU ps
implements it. A useful output
control to list IDs for processes, process groups, and sessions is
-j
, which is non-POSIX, but widely supported in practice.
Interestingly, macOS does support the session concept, but ps
and
other tools cannot display the session ID.
Selecting Fields
The POSIX standard suggests a default set of output fields: process
ID, terminal name, cumulative execution time, and command name. The
standard recognizes that defining different sets of fields is
difficult and introduced the -o
option for user-defined format
control.
The only two predefined output options specified for POSIX ps
are
the System V-derived -f
and -l
, which are the “full” and “long”
option, respectively. The default fields will be displayed with either
option.
The -f
flag is more user-focused, similar to (but less extensive
than) the BSD u
option. It also outputs the username and not the
UID. The -l
flag includes more scheduling and memory management
fields. Because process start time and username are displayed with
-f
, but not -l
, it makes sense to list both with -lf
.
The user-defined format control gives the most control over the output
of ps
. The macOS and GNU ps
implement a -O
option, which adds
fields to the default list. POSIX only specifies -o
.
The -o format
option expects a single, possibly quoted format
string that specifies comma- or space-separated output fields and
allows for renaming (or elimination) of headers. Multiple -o
options
can be used in one ps
command.
The equivalent to the default set of fields is:
ps -o pid,tty,time,comm=CMD
Not all fields have the same name as their header. The field for the
command name, which has CMD
as its header name, is comm
. Using the
=
allows for renaming; leaving the right-hand side empty leaves the
header blank.
The POSIX standard shows an example of spaces in header names, which
runs counter to the -o
option allowing space-separated field
names. The example does not work for GNU or macOS ps
.
Formatting ps
Output
There are no formatting options specified in the POSIX standard for
ps
. If the column width is insufficient ID fields will show numeric
instead of textual values.
While ps
should determine terminal width automatically, it can be
overridden with the COLUMNS
environment variable if need be. The
traditional BSD option for adjusting output width is w
: one w
switches to 132 columns, more than one selects unlimited width.
To suppress the header, the -o
option with empty renaming can be
used. GNU ps
also has a --no-headers
option. More portably, the
output of ps
can be piped to tail +2
, but this causes the screen
width to be ignored.
Some version of ps
have sorting options. GNU ps
has a --sort
option with the same field name syntax as -o
.
GNU ps
offers an ASCII art process tree with --forest
. For a
visually more appealing ps
output, the pstree
command has many
options.
For continuously updating ps
output, top
or the more powerful
htop
are the right tools.
Conclusion
This post is only a small insight into ps
options. Especially the
GNU version of ps
supports many different options and by setting the
PS_PERSONALITY
environment variable can emulate many different
systems’ ps
behavior. The manual pages ps(1)
are the reference for
the command and the GNU version would amount to 20 pages printed.
It is very useful to familiarize oneself with the common ps
options
for interactive use. Parsing the output programatically can be
challenging though and is rarely portable.