When I run the following command in csh
, I got nothing, but it works in bash
.
Is there any equivalent in csh
which can redirect the standard error to standard out?
somecommand 2>&1
When I run the following command in csh
, I got nothing, but it works in bash
.
Is there any equivalent in csh
which can redirect the standard error to standard out?
somecommand 2>&1
The csh
shell has never been known for its extensive ability to manipulate file handles in the redirection process.
You can redirect both standard output and error to a file with:
xxx >& filename
but that's not quite what you were after, redirecting standard error to the current standard output.
However, if your underlying operating system exposes the standard output of a process in the file system (as Linux does with /dev/stdout
), you can use that method as follows:
xxx >& /dev/stdout
This will force both standard output and standard error to go to the same place as the current standard output, effectively what you have with the bash
redirection, 2>&1
.
Just keep in mind this isn't a csh
feature. If you run on an operating system that doesn't expose standard output as a file, you can't use this method.
However, there is another method. You can combine the two streams into one if you send it to a pipeline with |&
, then all you need to do is find a pipeline component that writes its standard input to its standard output. In case you're unaware of such a thing, that's exactly what cat
does if you don't give it any arguments. Hence, you can achieve your ends in this specific case with:
xxx |& cat
Of course, there's also nothing stopping you from running bash
(assuming it's on the system somewhere) within a csh
script to give you the added capabilities. Then you can use the rich redirections of that shell for the more complex cases where csh
may struggle.
Let's explore this in more detail. First, create an executable echo_err
that will write a string to stderr
:
#include <stdio.h>
int main (int argc, char *argv[]) {
fprintf (stderr, "stderr (%s)\n", (argc > 1) ? argv[1] : "?");
return 0;
}
Then a control script test.csh
which will show it in action:
#!/usr/bin/csh
ps -ef ; echo ; echo $$ ; echo
echo 'stdout (csh)'
./echo_err csh
bash -c "( echo 'stdout (bash)' ; ./echo_err bash ) 2>&1"
The echo
of the PID and ps
are simply so you can ensure it's csh
running this script. When you run this script with:
./test.csh >test.out 2>test.err
(the initial redirection is set up by bash
before csh
starts running the script), and examine the out/err
files, you see:
test.out:
UID PID PPID TTY STIME COMMAND
pax 5708 5364 cons0 11:31:14 /usr/bin/ps
pax 5364 7364 cons0 11:31:13 /usr/bin/tcsh
pax 7364 1 cons0 10:44:30 /usr/bin/bash
5364
stdout (csh)
stdout (bash)
stderr (bash)
test.err:
stderr (csh)
You can see there that the test.csh
process is running in the C shell, and that calling bash
from within there gives you the full bash
power of redirection.
The 2>&1
in the bash
command quite easily lets you redirect standard error to the current standard output (as desired) without prior knowledge of where standard output is currently going.
tee
is the right tool for the job. Sending the data via tee
to both standard output and /dev/null
is no different to sending the data via cat
to just standard output. So I updated it with that option, but thanks for the info, it helped a lot. –
Hisakohisbe cmd >& /dev/stderr
actually totally screwed up my NoMachine session, even though the command was on a remote system from that session. I had upvoted this answer in the past, so presumably it worked in the past, but I am offering this second opinion to beware. –
Prospector I object the above answer and provide my own. csh
DOES have this capability and here is how it's done:
xxx |& some_exec # will pipe merged output to your some_exec
or
xxx |& cat > filename
or if you just want it to merge streams (to stdout) and not redirect to a file or some_exec:
xxx |& tee /dev/null
csh
, except using the trickery of temporarily calling a bash
shell. –
Hisakohisbe csh
. p.s. i can't believe it but... the solution for "how to merge stderr with stdout" via tee /dev/null
is the "best". ... smh –
Alanson As paxdiablo said you can use >&
to redirect both stdout and stderr. However if you want them separated you can use the following:
(command > stdoutfile) >& stderrfile
...as indicated the above will redirect stdout to stdoutfile and stderr to stderrfile.
xxx >& filename
Or do this to see everything on the screen and have it go to your file:
xxx | & tee ./logfile
pfctl -t bruteforce -T expire 259200 |& tee | grep -v '0/0 addresses expired.'
–
Sike What about just
xxx >& /dev/stdout
???
I think this is the correct answer for csh.
xxx >/dev/stderr
Note most csh are really tcsh in modern environments:
rmockler> ls -latr /usr/bin/csh
lrwxrwxrwx 1 root root 9 2011-05-03 13:40 /usr/bin/csh -> /bin/tcsh
using a backtick embedded statement to portray this as follows:
echo "`echo 'standard out1'` `echo 'error out1' >/dev/stderr` `echo 'standard out2'`" | tee -a /tmp/test.txt ; cat /tmp/test.txt
if this works for you please bump up to 1. The other suggestions don't work for my csh environment.
© 2022 - 2024 — McMap. All rights reserved.