在 C shell 中将 stderr 重定向到 stdout

当我在 csh中运行以下命令时,我没有得到任何东西,但是它在 bash中可以工作。 在 csh中有没有等价物可以将标准误差重定向到标准输出?

somecommand 2>&1
133130 次浏览

csh shell 从未因其在重定向过程中操作文件句柄的广泛能力而闻名。

您可以将标准输出和错误都重定向到一个文件,包括:

xxx >& filename

但这并不完全是您想要的,将标准错误重定向到 目前标准输出。


但是,如果您的底层操作系统公开了文件系统中进程的标准输出(就像 Linux 对 /dev/stdout所做的那样) ,您可以使用以下方法:

xxx >& /dev/stdout

这将迫使两个标准输出 还有标准错误到达与当前标准输出相同的位置,实际上与 bash重定向 2>&1相同。

记住,这不是 csh的功能。如果在 没有将标准输出公开为文件的操作系统上运行,则不能使用此方法。


不过,还有另一种方法。如果使用 |&将这两个流发送到 管道,则可以将它们合并为一个流,那么您所需要做的就是找到一个管道组件,该组件将其标准输入写入到其标准输出中。如果您没有意识到这一点,那么如果您不给 cat任何参数,它就正是这样做的。因此,在这个 具体点案例中,你可以通过以下方式达到你的目的:

xxx |& cat

当然,也没有什么可以阻止您运行 bash(假设它在系统的某个地方) 内心一个 csh脚本来为您提供增加的功能。然后,您可以使用这个 shell 的丰富重定向来处理 csh可能遇到困难的更复杂的情况。

首先,创建一个可执行的 echo_err,它将向 stderr写入一个字符串:

#include <stdio.h>
int main (int argc, char *argv[]) {
fprintf (stderr, "stderr (%s)\n", (argc > 1) ? argv[1] : "?");
return 0;
}

然后一个控制脚本 test.csh将显示它的行动:

#!/usr/bin/csh


ps -ef ; echo ; echo $$ ; echo


echo 'stdout (csh)'
./echo_err csh


bash -c "( echo 'stdout (bash)' ; ./echo_err bash ) 2>&1"

PID 和 psecho非常简单,因此您可以确保它是运行此脚本的 csh。当您使用以下命令运行此脚本时:

./test.csh >test.out 2>test.err

(初始重定向是由 bash 之前 csh启动运行脚本设置的) ,然后检查 out/err文件,您可以看到:

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)

您可以看到,test.csh进程 在 C shell 中运行,从 C shell 中调用 bash将为您提供完整的 bash重定向功能。

bash命令中的 2>&1很容易让您将标准错误重定向到 目前标准输出(如所需) ,而不需要事先知道标准输出当前的去向。

正如 paxDiablo 所说,您可以使用 >&重定向 stdout 和 stderr。然而,如果你想让他们分开,你可以使用以下方法:

(command > stdoutfile) >& stderrfile

... 如上所示,将把 stdout 重定向到 stdoutfile,把 stderr 重定向到 stderrfile。

我反对上述答案,并提供我自己的答案。 csh确实有这个能力,以下是它是如何做到的:

xxx |& some_exec # will pipe merged output to your some_exec

或者

xxx |& cat > filename

或者如果你只是想让它合并流(到标准输出)而不是重定向到一个文件或者 some _ exec:

xxx |& tee /dev/null

我认为这是 csh 的正确答案。

xxx >/dev/stderr

注意,在现代环境中,大多数 csh 实际上是 tcsh:

调侃者 > ls -latr /usr/bin/csh

Lrwxrwx 1 root 92011-05-0313:40/usr/bin/csh->/bin/tcsh

使用反勾嵌入语句将其描述如下:

echo "`echo 'standard out1'` `echo 'error out1' >/dev/stderr` `echo 'standard out2'`" | tee -a /tmp/test.txt ; cat /tmp/test.txt

如果这个方法对你有效,请提高到1。其他的建议对我的 csh 环境不起作用。

不如

xxx >& /dev/stdout

???

   xxx >& filename

或者这样做,可以看到屏幕上的所有内容,然后把它们存入你的文件:

  xxx | & tee ./logfile