It's all because of a person by the name of Albert D. Cahalan. Xe did not know BSD.
ps command for Linux was written and first published in March 1992 by Branko Lankester. It was later to become known as "kmem-ps" to distinguish it from "proc-ps" that was published in December 1992 by Michael K. Johnson. M. Lankester's
ps used the
kmem device to read the process table from kernel memory. M. Johnson's
ps used the
proc filesystem to read the process table, and there were several releases of it made over the next few years (e.g. January 1993, January 1994).
ps commands provided a fairly old, even then, syntax for the command whose style dated from the pre-
getopt() days of the 1980s. Here it is from a November 1993 release of kmem-ps:
usage: ps 0acefhHjlmnprsStuUvwxXy [t tty] [pid[,pid]...]
j -- job control format, l -- long format, m -- memory format,
s -- signal format, u -- user format, v -- virtual memory format,
X -- register format, y -- syscall format, default -- short format
0 -- include task zero, a -- include processes for all users
c -- print only command name, e -- show env vars, f -- print forest of procs
h -- suppress the header, n -- print the user and wchan fields numerically
p -- print counts in pages, r -- restrict listing to runnable processes
S -- summarize usage for children in CPU time and page fault fields
t tty -- show all proccesses with TTY as their controlling terminal
w -- wide: 132, ww -- 264, www -- unlimited, default -- screen width or 80
x -- include processes without a controlling terminal
U [SYSTEM-PATH [SWAP-PATH]] -- update ps database
As you can see, there was one personality, a single meaning for the letters, and no leading minus sign characters.
The idea of a
U flag (not
-U, notice) comes from a 1986 patch to BSD
ps by that was posted to the Usenet
mod.sources newsgroup (as Volume 6 Issue 83) by Michael A. Callahan.
Along came Albert D. Cahalan a few years later, who rewrote proc-ps. Xe made a lot of claims about it. Unfortunately, the debunking of a lot of those claims has been forgotten, and what stands all of these years later is the
ps manual claiming that this
ps provides Unix, BSD, and GNU option syntax.
It does not.
ps has used
getopt() option processing since Marc Teitelbaum changed it to do so in April 1990, years before even M. Lankester's version of Linux
ps, let alone M. Cahalan's.
ps provided the old Linux kmem-ps/proc-ps syntax. It later added some syntax that M. Cahalan claimed to be from the AIX
ps command. M. Cahalan, who adamantly propounded the view on Usenet that "BSD sucks and SysV doesn't" that FreeBSD "sucks" and that xyr rewrite of proc-ps was a "standards-compliant
/bin/ps" that supported "your obsolete BSD syntax", ironically was not aware that this had not in fact been the BSD syntax for almost a decade by that point.
ps itself had only just been standardized that year, moreover. The analysis in the standard's rationale of BSD versus AT&T Unix command-line options is a lot more thoughtful than any of M. Cahalan's ever were.
ps famously introduced the
I_WANT_A_BROKEN_PS environment variable, which confusingly M. Cahalan blamed on M. Johnson whilst simultaneously claiming xyrself to be responsible for the option parsing. In fact, the twain were maintaining two
ps implementations in parallel.
Bizarrely, if one used
getopt()-style options preceded by minus signs, as was the case for BSD
ps at the time and as the (then) new standard for
ps documented, Cahalan/Johnson
ps would state:
warning: `-' deprecated; use `ps e', not `ps -e'
Actually, it was not using
- that was deprecated. Indeed, the very claim made by M. Cahalan was that xyr
ps was going to work in the standard way using
- — like BSD
ps already had been. This caused numerous questions from perplexed users in the late 1990s and early 2000s, and generally confused the hell out of system administrators and users when books started saying things like:
You might be wondering why we don't use dashes before the flags with —Deborah S. Ray and Eric J. Ray (1998). UNIX. Peachpit Press. ISBN 9780201353952. p. 174.
ps. You can use them, but with
ps that's the old fashioned way and you get a warning about sticking with the program.
You can still see this discussed in the
oldps manual which talks of being "derived from the BSD version of
ps" although it really was not, it being fairly obviously derived from the Linux one; and which states that "command-line arguments should not be preceeded by a `-' character, because in the future, a `-' will be used to indicate Unix98-standard command-line arguments, while no `-' will indicate the current ``extended BSD'' style of command line arguments".
Some of this was toned down in procps-ng, a third rewrite that was done just after the turn of the century (when "-ng" in project names was à la mode), which is when Cahalan/Johnson
oldps. As you can see, the
ps manual no longer says "extended". But the new version of
ps (which still involved M. Cahalan) did take the whole multiple-personality idea to extremes. Unfortunately, moreover, it still perpetuated the canard about BSD command-line options, and does so to this day.
In the meantime, the happily single-personality BSD
ps has provided
getopt() command-line option parsing for the past 29 years and 7 days at the time of writing this answer; FreeBSD has gained a
procstat command; the NetBSD and OpenBSD
ps has tracked the new compromise
-A option; and the Single Unix Specification has reserved (but not included) the new BSD
-O option to
- Robert N. M. Watson (2017-01-14).
procstat. FreeBSD General Commands Manual.
ps. FreeBSD General Commands Manual. 2018-03-13.
ps. NetBSD General Commands Manual. 2016-12-02.
ps. OpenBSD General Commands Manual. 2016-10-26.