X

News, tips, partners, and perspectives for the Oracle Solaris operating system

Teaching an old ps command new tricks

Alan Coopersmith
Senior Principal Software Engineer

Last year, while debugging a GNOME issue, one of our engineers filed a bug report that stated:


When running gnome-tweak-tool from console and trying to add a new Startup
Application, the following error is dumped into the console:

ps: illegal option -- w
ps: illegal option -- w
ps: unknown output format: -o cmd
usage: ps [ -aAdefHlcjLPWyZ ] [ -o format ] [ -O format ] [ -t termlist ]
        [ -u userlist ] [ -U userlist ] [ -G grouplist ] [ -h lgrplist ]
        [ -p proclist ] [ -g pgrplist ] [ -s sidlist ] [ -z zonelist ]
  format is one or more of:
        user ruser group rgroup uid ruid gid rgid pid ppid pgid sid psr lwp
        lname nlwp opri pri f s c pcpu pmem osz vsz rss rssprivate rssshared
        nice class stime etime time tty addr wchan fname comm args taskid
        projid project pset zone zoneid ctid lgrp env fmri

It doesn't seem to have any negative effect on the tweak-tool and I can still
select applications which do correctly start when machine is restarted, but it
should not appear.

When getting bug reports like this, while we can always just patch the code to make it use options that the existing Solaris code supports, we also consider if we should modify Solaris to support these options. I looked around at other versions of the ps command on other platforms, and at our ps code, and saw it would not be hard or risky to add these options to our command, so we wouldn't have to have another difference from other platforms added to our GNOME packages, and would likely help both scripts and users coming from other platforms which have those options.

So starting in Oracle Solaris 11.4.27 (released to support customers on November 18), /usr/bin/ps sports a number of changes:

  1. Adds long option equivalents for some short options
  2. Adds new options for new criteria to select which processes to print
  3. Adds new keywords for the format options to select which columns of data to print for each process
  4. Adds aliases for some format option keywords
  5. Adds new options for header handling
  6. Adds the -w option to support line width setting and comes into line with the new POSIX draft
  7. Adds the --human-readable option to scale memory sizes
  8. Improves the ps(1) man page

1. Long Option Equivalents for Existing Options

The Solaris ps command now accepts these long options as equivalents to the existing short options it already had. The --lgroup option is a Solaris invention, while the rest of these are also accepted by the Linux ps command.

New long option Existing short option
--format=format -o format
--Group=gidlist -G gidlist
--help -?
--lgroup -h
--pid=proclist -p proclist
--sid=sidlist -s sidlist
--tty=term -t term
--user=uidlist -u uidlist
--User=uidlist -U uidlist

While options taking arguments are listed here in the standard “--option=argument” form, “--option argument” is also accepted.

2. New Selection Criteria Options

The ps command has long provided a number of options to select which processes to list. This project added a few more:

Option Matches on Also found on
-C cmdlist Command name Linux, HP-UX
--group=gidlist Effective group Linux
--ppid=proclist Parent process id Linux

Since the traditional behavior of the -g flag requires all-numeric values be specified, the Linux ps examines the arguments to -g, and if any are non-numeric, accepts -g as a short equivalent of --group. This project introduced similar behavior on Solaris, with -g mapping to either --pgid (the traditional behavior on Solaris) or --group depending on the arguments.

3. New Format Option Keywords

The ps command also allows you to specify what columns of data to list for each command, either using -o to specify the full list of fields, or -O to add, remove, or modify fields in the existing display.

This project added these format keywords to select which columns to list:

Keyword Prints Also found on
dmodel Data model as _LP64 or _ILP32 illumos
etimes Elapsed time in seconds Linux, FreeBSD
label TX label or process clearance Linux, FreeBSD
sgid Saved group id as integer Linux
sgroup Saved group id as username Linux
suid Saved user id as integer Linux
suser Saved user id as username Linux
times CPU time in seconds Linux

Linux & FreeBSD define label as a Mandatory Access Control (MAC) label, so this has been mapped to the rough equivalent on Solaris - the zone label if Trusted Extensions is in use, otherwise the process clearance.

The saved user and group ids are read from the /proc/pid/cred file, which has restricted access, so most normal users will only see ? in those columns, making those options most useful to users with higher privilege levels.

4. Format Option Aliases

Different platforms have had different keywords for use with the -o and -O options over the years, so this project introduced to the Solaris ps the concept of aliases for format keywords, in which providing the alias as a format argument operates exactly as if the aliased format keyword was specified.

Alias Keyword Also found on
%cpu pcpu Linux, FreeBSD, OpenBSD
%mem pmem Linux, FreeBSD, OpenBSD
clearance label Solaris invention
cls class Linux
cmd args Linux
command args Linux, FreeBSD, OpenBSD
cputime time Linux
cputimes times Linux
egid gid Linux
egroup group Linux
euser user Linux
flag f Linux
flags f Linux, HP-UX, FreeBSD, OpenBSD
lgroup lgrp Solaris invention
ni nice Linux, FreeBSD, OpenBSD
pgrp pgid Linux
policy class Linux
rssize rss Linux
rsz rss Linux, OpenBSD
sess sid Linux
session sid Linux
svgid sgid Linux, OpenBSD
svuid suid Linux, OpenBSD
tname tty Linux
tt tty Linux
ucmd comm Linux
ucomm comm Linux, FreeBSD, OpenBSD

5. Header Handling Options

This work added these options to give more control over the display of the column header line.

--headers
Prints the headers once per page. Page size is determined by the first found of:
  1. The last specified value of either a --rows or --lines option on the command line.
  2. The LINES environment variable.
  3. If output or input is a tty, the tty height.
--no-headers, --no-heading
Omit the column headers from the output.
--rows=rows, --lines=rows
Specifies the number of rows per page of output, overriding the LINES environment variable. See the --headers option for details.

All of these options are supported by the Linux ps. The FreeBSD & OpenBSD ps provide a -h option for the --headers functionality, but Solaris ps already uses -h for selecting “processes homed to the specified lgrplist”, so we can't do that. Similarly, the -H flag normally used in other Solaris commands for --no-headers is already used in Solaris ps for printing home lgroups, so we've left it without an equivalent short option.

6. Line Width Handling Options and Changes

Previously, Solaris ps defaulted to not having a line length limit. If -W was specified, then lines were limited to the first found of:

  1. $COLUMNS environment variable
  2. If stdout or stdin is a tty, the tty width.

Meanwhile, the Austin Group has accepted a proposal to standardize the -w option to ps for the next version of the standard based on it being implemented in nearly every other version of ps, but has left some flexibility in the implementation. The accepted change from https://austingroupbugs.net/view.php?id=905 is:

   -w behave as if the COLUMNS environment variable had a value
      of at least 132. If the -w option is not specified or is
      specified exactly once, all output lines shall contain no
      more than the greater of {LINE_MAX} and COLUMNS bytes
      provided that no format name is specified multiple times.

   Portable applications should not set COLUMNS to a value greater
   than {LINE_MAX} and should not specify the -w option more than
   once if the output will be used as input for a utility that
   requires a text file as input because lines containing more
   than {LINE_MAX} bytes may cause undefined behavior in some
   implementations of the utility.

So this project updated Solaris ps to accept -w flags, and to follow the draft POSIX standard.

When no -w options are specified, lines are now limited to the columns setting. If any of the --columns, --cols, or --width options are used, the columns setting is the value from the last one of those options on the command line. If none of those options are provided, the value of the COLUMNS environment variable is used for the columns setting. If neither the options or environment variable is set, then if the output is a tty, the terminal width is used, otherwise the value of LINE_MAX is used. (On Solaris, LINE_MAX is set to 2048 columns, as you can see by running getconf LINE_MAX in a Solaris shell.)

If -w is specified exactly once, lines are limited to 132 characters of output. If -w is specified two or more times, lines are unlimited, matching the default status before this change.

This effectively makes the previous behavior of -W the new default on Solaris. The -W flag will still be accepted, but will now serve as a reset to clear any -w, --columns, --cols, or --width options that precede it on the command line.

7. --human-readable option

Besides looking at what other versions of ps did, I also looked at what bugs and enhancement requests had been made by Solaris users in the past. Some small bugs got fixed, and the code cleaned up, but one noticable enhancement was included as well. The Solaris ps now accepts the --human-readable option to request scaled values for memory sizes in output.

For example, lines from ps -e -o pid,osz,vsz,rss,rssprivate,rssshared,fname without --human-readable:

    PID    SZ   VSZ     RSS    RSSPR    RSSSH COMMAND
      1  1243  4972    2396     2392        4 init
    773 16186 64744   18272    18212       60 nscd
    988 123305 493220 13256    13244       12 fmd
   1149 85616 342464  79716    79692       24 sstored
  28804 284299 1137196 577160 453500   123660 firefox
  28781 505088 2020352 1300220 1298292   1928 thunderbird
  17117 235942 943768 873244  199104   674140 VirtualBoxVM

with --human-readable:

    PID    SZ   VSZ     RSS    RSSPR    RSSSH COMMAND
      1 4.85M 4.85M   2.34M    2.34M       4K init
    773   63M   63M     17M      17M      60K nscd
    988  482M  482M     13M      13M      12K fmd
   1149  334M  334M     76M      76M      24K sstored
  28804 1.08G 1.08G    523M     402M     121M firefox
  28781 1.92G 1.92G   1.22G    1.22G    1.87M thunderbird
  17117  922M  922M    853M     194M     658M VirtualBoxVM

When --human-readable is not in use, the "SZ" column is reported as the number of pages, while the rest are in number of kilobytes. When it's in use, all of the size columns are scaled by repeatedly dividing the number of bytes by 1024.

The review of this feature also caused us to take a look at how we handle similar options in other Solaris commands, and a project was started for a later SRU to bring more consistency and configurability to the scaled unit display across the Solaris command set.

8. Man page improvements

While updating the man page, I also took care of a few existing bugs and enhancement requests there as well. While you can't see this yet in the docs.oracle.com version of ps(1), you can view it via the man command after upgrading to SRU 27.

The options accepted by /usr/ucb/ps are now clearly separated into the UCB options subsection of the man page. The DISPLAY OPTIONS section has been reorganized to be easier to follow. Information about the other options for specifying columns has been gathered into a new Historical Output Formats subsection. The new DISPLAY WIDTH section covers the changes described above. A new table in the NOTES section shows where in /proc programs can find the data that ps shows for each field. And finally, a new HISTORY section shows when each option and format keyword was added so that those working with systems on different releases can more easily know what options they can use across those different systems.

Join the discussion

Comments ( 3 )
  • DavidH Monday, December 7, 2020
    Nice to see the -w and -ww
    Those were around on the sun3/50 workstations!
  • PRESSY Wednesday, December 16, 2020
    if you are already thinking about filters a --project= would be nice and save awk-one-liners ;-)

    thanks for that nice work!
  • Alan Coopersmith Tuesday, December 22, 2020
    Seems like a reasonable request - I've filed enhancement 32313169 - ps(1) could use a flag to select by project - to record it.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.