Subject: VERY strange command-line syntax for 'df -t'
To: NetBSD Userlevel Technical Discussion List <tech-userlevel@NetBSD.ORG>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 04/07/2002 18:52:46
I just submitted a fix for pkgsrc/net/netsaint-plugins that includes a
change to the way the NetBSD "df" command usage is specified for that
package.

In coming up with that change I was somewhat stunned by the bizzare
syntax for the '-t' option (esp. so in that I don't recall ever noticing
this oddity before).  While the language in the documentation is
strictly accurate, it's not exactly clear, at least not without an
example.

     -t type
             Is used to indicate the actions should only be taken on filesys-
             tems of the specified type.  More than one type may be specified
             in a comma separated list.  The list of filesystem types can be
             prefixed with ``no'' to specify the filesystem types for which
             action should not be taken.  If a file system is given on the
             command line that is not of the specified type, a warning is is-
             sued and no information is given on that file system.

Using a single 'no' prefix to negate an entire comma-separated list is
very much contrary to the principle of least surprise.  Unfortunately
this violation of TPoLS also affects fsck(8), mount(8), and umount(8).

Now I realise that when no filesystems are indicated as operands on the
command line there's no implied default "basic" list of filesystem types
(which might be a subset of the list of all types) so in that case
there's no need for a way to express both inclusive and exclusive logic
in the same list.  However when filesystem(s) are given on the the
command line the allowance for inclusive and exclusive logic would make
sense.

Even so the merging of the list negation operator with the first word in
the list, especially when that operator is itself "word like", is
contrary to many other scenarios where this is normally only done on a
per-item basis.  My brain baulks completely at the site of this construct.

I think this should be fixed, and in doing so I think 'df -t' should be
changed completely over to the Single UNIX Specification usage ("Include
total allocated-space figures in the output") and a new, hopefully
better designed, argument be used to specify the filesystem type list
with both inclusive and exclusive logic allowed.

I was going to implement my suggestion, but because of the possible
variations in the fix I decided it would be less effort to first talk
about it first and see where any consensus might lay.  (Also, adding
more local changes to 'df' would make it a lot harder for me to submit
another local change I've been harbouring until my next "big merge".... :-)

First the logic fix.  I see two practical alternatives, and two common
variants of these alternatives.  The variation is to use the '!' as a
negation symbol instead of the word "no".

1. The first is to separate the negation operator with some special
   character:

	-t no:nfs,mfs
	-t !:nfs,mfs

2. The second is to require the negation operator on every word in the
   list, as per other similar item lists used in some cases on other
   arguments by some of these same commands (eg. mount(8)):

	-t nonfs,nomfs
	-t !nfs,!mfs

A less likely alternative is to use a separate command-line flag to
indicate a negation of the list given.  This seems too invasive though,
especially given the number of commands involved, and the fact that in
at least one of the affected commands would have a clash with the
obvious choice, as would 'df' itself if we include other SuSv2 fixes.

The second alternative, with the first variation is probably the best
because it is completely compatible with the current syntax.  I.e. just
allow 'no' to prefix each item in the list:

	-t nonfs,[no]mfs

and if not all items are prefixed with "no" perhaps to warn (to stderr?)
of the affect of the deprecated syntax:

	$ df -t nonfs,mfs
	WARNING: '-t no*' implies the whole list is negated.
	...

and to allow the currently "silly" logic of "-t mfs,nonfs" which would
of course be equivalent to "-t mfs".

It would though be less confusing (especially during the deprecation
period) to use the syntax in the first alternative, and there's already
some prior art for such a construct, even within the effected commands.

(though if I were to do the implementation I'd also implement '!'
because I've never really liked the use of "no" as a negation operator)


(note that all of the above, and even the current implementation [except
for its clash with '-t' in "df"], are well within the command-line
syntax design guidelines of SuSv2)



Now, what to call it so as to not clash with SuSv2 '-t'?  I suggest '-T'

(BTW, I don't have any issue whatsoever with having a different "fs
types" option for "df" vs. the likes of "fsck" et al -- the former is a
standardised end-user command and which is part of the system
programming interface, while the latter are all administrative commands
that are not even specified by most unix-ish standards such as SuSv2)


I've no suggestion as to how to gracefully and compatibly handle the
change from 'df -t' to '-T' while also including the new SuSv2 '-t',
other than "Just Do It!"  (it's ``hard'' to parse a SuSv2 command-line
and allow for an flag to have optional operands, especially when the
command itself takes optional non-flag operands)

-- 
								Greg A. Woods

+1 416 218-0098;  <gwoods@acm.org>;  <g.a.woods@ieee.org>;  <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>