在 C shell 中将标准错误重定向到标准输出

Posted

技术标签:

【中文标题】在 C shell 中将标准错误重定向到标准输出【英文标题】:Redirect stderr to stdout in C shell 【发布时间】:2012-11-23 02:27:42 【问题描述】:

当我在csh 中运行以下命令时,我什么也没得到,但它在bash 中有效。 csh 中是否有任何等效项可以将标准错误重定向到标准输出?

somecommand 2>&1

【问题讨论】:

CSH 很危险。尝试切换到 bash,zsh faqs.org/faqs/unix-faq/shell/csh-whynot @SSHegde 你说的“危险”是什么意思? @Geza:请参考我在评论中提到的链接。这就解释了原因。 @SSHegde 我希望我可以为您的“csh-whynot”链接加注星标 【参考方案1】:

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

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

xxx >& filename

但这并不是你所追求的,将标准错误重定向到 current 标准输出。


但是,如果您的底层操作系统在文件系统中公开了进程的标准输出(就像 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 的echops 很简单,因此您可以确保它是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 中运行,并且从那里调用 bash 为您提供了完整的 bash 重定向功能。

bash 命令中的2&gt;&amp;1 很容易让您将标准错误重定向到当前 标准输出(根据需要),而无需事先知道标准输出当前的去向。

【讨论】:

您好,这可以通过稍微修改 bioffe 的响应使用 csh 来完成。您想要的是合并 stderr 和 stdout 流而不是文件。 'xxx |& tee /dev/null' 也是如此,这将产生组合流的效果,将它们发送到假文件,但也将两者发送到屏幕上的 STDOUT(或您使用 stdout 的任何地方)。请使用此选项更新此答案。 @mdiehl13,实际上,这是一个很好的观点,我没有考虑过。但是,我不确定tee 是否适合这项工作。通过tee 将数据发送到标准输出和/dev/null 与通过cat 将数据发送到just 标准输出没有什么不同。所以我用那个选项更新了它,但感谢你提供的信息,它有很大帮助。 cmd &gt;&amp; /dev/stderr 实际上完全搞砸了我的 NoMachine 会话,即使该命令位于该会话的远程系统上。我过去曾赞成这个答案,所以大概它在过去有效,但我提供第二个意见以提防。【参考方案2】:

正如paxdiablo 所说,您可以使用&gt;&amp; 来重定向stdout 和stderr。但是,如果您希望它们分开,您可以使用以下内容:

(command > stdoutfile) >& stderrfile

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

【讨论】:

这个答案应该有更多的选票恕我直言。是否有一些我看不到的负面影响? 我认为这是正确的答案.. 其他接受的答案没有回答问题! @Charbel,它不会将 stderr 重定向到 current 标准输出,而是将两者都重定向到 new 位置。【参考方案3】:

我反对上述答案并提供我自己的答案。 csh 有这个功能,它是如何完成的:

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

xxx |& cat > filename

或者如果您只是希望它合并流(到标准输出)而不是重定向到文件或 some_exec:

xxx |& tee /dev/null

【讨论】:

@chris,这允许您将 stdout 和 stderr 发送到同一个地方,但它确实 not 允许您将标准错误传送到 current 标准输出。所以无论如何都要投票,只是要知道它没有回答问题。 OP 要求的内容不能用 csh 完成,除非使用临时调用 bash shell 的诡计。 虽然 csh 中没有完全等价的,但您的答案仅涵盖了当您想要将 stdout 和 stderr 都重定向到文件时的用例。这个答案还演示了如何将它们重定向到管道中。 @chris,这个问题需要一种将 stderr 定向到当前标准输出的方法,而不是如何将它们都定向到一个全新的位置(无论是文件还是管道)。后者可以通过我的答案的第一部分或这个答案来完成,但 csh 无法做到前者。如果您阅读了我的回答的第二部分(暂时从 csh 调用 bash,现在通过一个具体示例进行扩展以希望澄清),那就可以了。 难以置信...这个解决方案是csh 的“最佳”解决方案。 p.s.我不敢相信,但是...通过tee /dev/null“如何将标准错误与标准输出合并”的解决方案是“最好的”。 ... smh【参考方案4】:

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

xxx >/dev/stderr

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

rmockler> ls -latr /usr/bin/csh

lrwxrwxrwx 1 root root 9 2011-05-03 13: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 环境。

【讨论】:

【参考方案5】:

刚刚呢

xxx >& /dev/stdout

???

【讨论】:

这确实提供了问题的答案,但它可能不应该带有问号,因为看起来发帖人不确定这是否回答了问题。【参考方案6】:
   xxx >& filename

或者执行此操作以查看屏幕上的所有内容并将其转到您的文件中:

  xxx | & tee ./logfile

【讨论】:

以上是关于在 C shell 中将标准错误重定向到标准输出的主要内容,如果未能解决你的问题,请参考以下文章

重定向

Shell 环境中的输入输出重定向

Linux下Shell重定向

重定向标准错误到标准输出 是啥意思

Shell标准输入标准输出和标准错误的重定向总结

shell从入门到精通(13)输出重定向