I did some experiments with directing to /dev/stderr in a tcsh script. My
intention was for the user of the script to be able (also in tcsh) direct
standard output and standard error to different places. I found that the
script had to look like:
echo 1ABC >>& /dev/stderr
echo 2ABC >>& /dev/stderr
If you do not use >>, then in the redirected script output, you lose
some of the standard input and/or standard output data. Even so, redirecting
the output of the script to a file using a simply >& does not work; it too
loses part of standard error (even on bash). You must use a
(SCRIPT >! file.out ) >&! file.err
construct. Here either file or both can be /dev/tty for output to the screen.
(If you do not redirect the script output, there is never a problem.)
Note that none of this weirdness occurs if you direct to standard error from
inside a program.
Also note that this was on Linux (Ubuntu-MATE LTS 16.04, to be precise). Of course you need at least /dev/stderr to exist for the above to be usable.
After posting this, I found still another issue. If you put a program that writes to standard error after the 1ABC line, then the 1ABC gets lost if you
direct standard error to a file. The good news is that in my case, standard
error must continue to go to /dev/tty. Gee. :)
To allow for easy modification, and systems without /dev/stderr, I have decided to implement this through the following two header lines
alias stderr echo ; if (-ew /dev/stderr) alias stderr 'echo \!* >> /dev/stderr'
which echo_err > /dev/null ; if !($status) alias stderr echo_err
This allows the user to put a sh script echo_err,
echo $* 1>&2
in the path if bug-free redirection of standard error is really needed (at the
expense of two image activations).
Another addition: My post above was about issues in redirecting to /dev/stderr
within tcsh. But as long as I am giving aliases, maybe I should also give
one for Glen Ragan's solution, which is really very nice if you do not mind
an image activation. Define
alias 1to2 '\!* | sh -c "cat 1>&2"'
alias 2to1 '\!* |& cat'
Then you can precede any command for which you want standard output to be redirected to stdout by 1to2. That acts then just like preceding the command by 1>&2 in other shells, including DOS. And it is not buggy in Linux. May as well have a 2to1 too, then. :)
OOPS: A minor flaw in 1to2 above: if the command writes to both standard output and standard error, the order is wrong. The command's standard error stuff ends up before its standard output stuff in the final standard error result. The solution is simple; change | into |&:
alias 1to2 '\!* |& sh -c "cat 1>&2"'
Sorry about that.