How "ps" works and why
The simple "ps" command has generated a fair amount of
confusion. Almost every Unix variant does it slightly differently;
flags have different meanings and column headers or position also
differ. This wreaks havoc with cross-platform scripts and has also
caused bitter comments now and then. As I explained at I_WANT_A_BROKEN_PS , I had the same
misunderstandings. Albert Cahalan (author of the Linux procps package, which includes
"ps") noticed a newsgroup thread where I had made such a comment,
and took the time to reply to me.
After reading his explanation, I
understand that I was quite wrong.
Albert gave me permisson to quote from his email:
There's an ongoing effort to gently transition to new syntax.
It goes like this:
1. add a warning about the obsolete syntax
2. add the new syntax for a non-default personality
3. make the new syntax be the default
4. if the old syntax was really evil, remove it
I try to make this happen over a period of several years,
so that nobody gets caught by surprise. Unfortunately,
many Linux distributions like to patch out the warnings.
Their users will suffer horribly when things break in
some future release. To combat this, I break the rotten
patches by adding comments that explain the problem.
Everyone but Slackware has gotten the message by now.
Right now, "-x" is in the hpux personality. When I add
it to the default personality next year, "ps -ax" will
no longer issue a warning and fall back to "ps ax".
I'm pretty much waiting for Fedora to go out as Red Hat
first, and giving Slackware one last chance to warn people.
As to current behavior...
There is no oldps anymore. It was, literally, the old ps.
(there was a complete rewrite) You get 90% of oldps by
setting PS_PERSONALITY=old though.
Doing "ps -e" is always legit, though the meaning differs
by personality. You'll get a warning from "ps -u" though,
because that's only legit in BSD-like personalities.
The e and -e should mean...
oldps -e display the environment, with warning
PS_PERSONALITY=old ps -e display the environment
ps -e show every process
oldps e display the environment
PS_PERSONALITY=old ps e display the environment
ps e display the environment
The old ps had an I_WANT_A_BROKEN_PS variable that you
could set to disable the warning. The new ps interprets
this as setting PS_PERSONALITY=old, which makes it OK
to start BSD options with a "-".
It's not bad to start BSD options with a "-" if you've
given some indication that you actually want ps to interpret
them that way, so there isn't a warning. The warning is
delivered when you rely on your BSD options to be illegal
in the UNIX syntax. To rely on this is dangerous, because
your usage will fail as more UNIX options are added.
The warning amounts to saying "hey, if I add an -x option,
your ps command will have radically different behavior".
As it is, a Google query found one person who noticed that
"ps -aux" breaks when a user named "x" is created. :-(
This person was unaware of the danger because their Linux
distribution had patched out the warning.
Notice the comment about distros patching out the warnings?
Perhaps there would have been less confusion had they not done
So, Albert is trying to make "ps" righteous, but also trying to
avoid doing it too quickly. That's a tough road to walk, I
Albert explained some of the details behind PS_PERSONALITY
Well, oldps was discontinued 2 years ago. The latest procps
is version 3.2.2 at Procps - The /proc file system utilities now.
The personality stuff can change the columns that get output.
Try CMD_ENV=irix with "ps -l" for example. The "digital"
personality changes most formats by a column or two. There's
the choice of 4-column or 5-column default output, and the
choice to include processes on other TTYs by default or not.
There's "ps -opid,ppid=MOM,stat,comm" behavior.
Much of it is done via some flags. From my memory...
#define PER_BROKEN_o 0x0001
"ps -opid,ppid=MOM,stat,comm" is 2 columns
#define PER_BSD_h 0x0002
"h" will repeat the header once per screenful
of output instead of disabling the header
#define PER_BSD_m 0x0004
"m" does sorting by memory usage
(instead of thread display)
#define PER_IRIX_l 0x0008
"ps -l" does a funny ADDR:SZ (or SZ:RSS?) column.
#define PER_FORCE_BSD 0x0010
"ps -aux" is interpreted as "ps aux", you get a
5-column display be default, and the default selection
will include processes on other TTYs
#define PER_GOOD_o 0x0020
"ps -opid,ppid=MOM,stat,comm" is 4 columns
#define PER_OLD_m 0x0040
"m" is the old memory usage format
(instead of thread display)
#define PER_NO_DEFAULT_g 0x0080
process selection like SunOS 4 (need "ps axg" to see all)
#define PER_ZAP_ADDR 0x0100
replace the ADDR column with RSS
#define PER_SANE_USER 0x0200
column with usernames titled "USER", not "UID"
#define PER_HPUX_x 0x0400
show command args and do a wide display
#define PER_SVR4_x 0x0800
-x acts like -y
So, sadly, CMD_ENV=sco just sets PER_SVR4_x and PER_BROKEN_o.
As you can see, there's a lot of potential confuson here. Here's
I've always felt that the man page was a bit terse, but that
getting wordy would be inappropriate for a man page. I'm not
a fan of info pages, since I never remember to check them myself.
This comment on your web site shocked me:
"Regarding the ps semantics, I really don't appreciate
some of these ADD-suffering coders intentionally deviating
from the POSIX standards so as avoid typing one or two
Woah. The whole POINT of the changes is to meet the POSIX
standard! The POSIX standard will parse "ps -aux" for sure,
but not in a way that BSD fans could tolerate. I'd expected
former SCO users to use "ps -ef" and recognize what "ps -aux"
does on a Real UNIX system. Simply pretend that Linux is SysV.
Stick to the UNIX syntax and you'll never see a warning.
My ultimate hope is to unify things, to the extent that an
admin can sit down at any UNIX-like system and expect that
both "ps -ef" and "ps aux" will work. I seem to have the
FreeBSD developers 60% convinced. Sun merely needs to cause
/bin/ps to run /usr/ucb/ps when an unparsable option is
found or when the first arg lacks a "-". AIX and Tru64 already
support both syntaxes. In fact, Tru64 (then called OSF/1) is
where I got the idea from in the first place.
I've been thinking of submitting the BSDisms to be included
in the UNIX standard. I almost did last time, but real-life
events got too intense for me to write up the spec in time.
I'd leave out the ability to mix BSD syntax with UNIX syntax,
so that Sun would have an easy time complying.
So, as you see, he's really working hard to "do the right thing"
Got something to add? Send me email.
More Articles by Tony Lawrence
Find me on Google+
© 2011-03-20 Tony Lawrence