Inconsistency of stderr redirection between tcsh and other shells

This inconsistency is in fact the first reason in the list of reasons why csh programming is considered harmful.

Or what if you just want to throw away stderr and leave stdout alone? Pretty simple operation, eh?

cmd 2>/dev/null

Works in the Bourne shell. In the csh, you can only make a pitiful attempt like this:

(cmd > /dev/tty) >& /dev/null

But who said that stdout was my tty? So it's wrong. This simple operation CANNOT BE DONE in the csh.


2> is not an operator in tcsh, you're using the > operator and passing 2 as an argument to vi. This appears to be okay since both --xxx and --version exit vi.

From tcsh(1):

   > name
   >! name
   >& name
   >&! name
           The file name is used as standard output.  If the file does not
           exist then it is created; if the file exists, it is  truncated,
           its previous contents being lost.

           If  the shell variable noclobber is set, then the file must not
           exist or be a character  special  file  (e.g.,  a  terminal  or
           `/dev/null')  or an error results.  This helps prevent acciden‐
           tal destruction of files.  In this case the `!'  forms  can  be
           used to suppress this check.

           The  forms  involving  `&' route the diagnostic output into the
           specified file  as  well  as  the  standard  output.   name  is
           expanded in the same way as `<' input filenames are.

So you can use >& to redirect both stdout and stderr ("diagnostic output"). There is no "obvious" way to only redirect stderr, and this is a long-standing shortcoming of the C shell, a well-known workaround is:

(vi --xxx > /dev/tty) >& /dev/null

This works by redirecting stdout to /dev/tty (which is the current tty) in a subshell (the parens do the same as in bourne shells), and the output of the subshell (which is only stderr since we redirected stdout) is redirected to /dev/null (but this can be anything, like a file).

I don't know what your goal is, but in cases where you can't be sure what shell the user is using, I've found that it's usually best to explicitly set it; there are more shells than "bourne and csh", such as fish, and there may also be slight incompatibilities between different Bourne shells and/or some constructs may "happen" to work in one shell, and don't in another...