Redirect stdout to stderr in tcsh
Solution 1
Concerning csh
, from http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/:
Along these same lines, you can't direct error messages in csh scripts out stderr as is considered proper. In the Bourne shell, you might say:
echo "$0: cannot find $file" 1>&2
but in the csh, you can't redirect stdout out stderr, so you end up doing something silly like this:
sh -c 'echo "$0: cannot find $file" 1>&2'
I did some quick tries with tcsh
, and as suspected it appears to be true for that as well (tcsh
is supposed to be fully compatible with csh
).
To address your formulated question: it wouldn't matter if you could make tcsh
not "insert spaces" since it will not interpret that sequence in the intended way anyway.
Solution 2
EDIT:
I didn't see this was tsch. See the "Input/output" section of man tsch
for details including this:
Diagnostic output may be directed through a pipe with the standard output. Simply use the form |& rather than just |.
The shell cannot presently redirect diagnostic output without also redirecting standard output, but (command > output-file) >& error-file is often an acceptable workaround. Either output-file or error-file may be /dev/tty to send out-put to the terminal.
Solution 3
Daniel Andersson's solution is great and will work well if the command you want to run can be run from sh (and, therefore, a subshell, which will be unable to change the directory or modify the environment of your current shell). If you want to convert stdout to stderr but keep the command execution in the current shell, you can use bash only for the stdout-to-stderr redirection, like this:
echo "An error message" | bash -c "cat - 1>&2"
Solution 4
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
echo 1ABC >>& /dev/stderr
echo 2abc
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,
#!/bin/sh
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.
Related videos on Youtube
Jeff Dunbar
http://twitter.com/thenatealator http://news.ycombinator.com/user?id=natep https://github.com/nsp (mostly abandoned projects because I'm bad at Githubbing, sorry!)
Updated on September 18, 2022Comments
-
Jeff Dunbar over 1 year
From my understanding, the following should send '
test
' on standard error in tcsh:echo test >&2
However, it instead writes '
test
' to a file named2
, and when I look through my history, I find that what actually executed wasecho test > & 2
I'm not sure what layer is inserting those spaces, but can I stop it somehow? If not, I guess I could always use
> /dev/stderr
instead.-
Oliver Salzburg almost 12 years
echo test >&2
prints to stderr. At least in my bash. -
Oliver Salzburg almost 12 yearsBTW, using
>
as a shell indicator is pretty confusing in your code snippets in the current context ;) -
Dave Forgac almost 12 yearsI assumed bash at first as well but it's tagged tsch.
-
Jeff Dunbar almost 12 yearsSorry about the confusion, hopefully my question is more clear now. If I could use bash here, I would, since it works for me.
-
kevlar1818 almost 12 yearsCould you quote the redirect?
echo test '>&2'
? No idea if that works, and don't have tcsh to try it. -
Jeff Dunbar almost 12 years@kevlar1818 tried that, and it treats >&2 as a second argument to echo, not a redirect command
-
kevlar1818 almost 12 years
echo test >"&2"
is my only other guess.
-
-
Jeff Dunbar almost 12 yearsThanks for pointing that out, but I'm not sure it applies. I don't want to redirect the diagnostic output (stderr?) of a process, instead I want the normal output to appear on stdout.
-
Oliver Salzburg almost 12 years@drhorrible: It's essentially the same thing. What you're doing is starting the
echo
process and redirecting its output to stderr. Thus, printing to stderr effectively :) -
Jeff Dunbar almost 12 yearsThat's not how it seems to work.
(echo test > out) >& err
writes 'test' to a file called 'out' and creates an empty file 'err' on my machine, at least. -
Randall over 6 yearsThis is a good way to get
STDOUT
andSTDERR
split from a command sending output to both, and send them to files. However, it does not answer the OP's question on how to forceSTDOUT
(which is where echo sends output) to go toSTDERR
in tcsh.