为什么'>'不重定向来自 gcc 的错误消息?

为什么'>'不重定向来自 gcc 的错误消息?

我将以下程序存储在 new.c 中

int main() 
{ 
    a;
    return 0; 
}

它返回一条错误消息。我想将此消息发送到文件。因此我使用了以下命令

gcc new.c > temp.txt

但我仍然在终端上得到了输出。我正在使用 Ubuntu 13.04。我该如何让它工作?

答案1

使用 编译程序时gcc,输出有多种类型:到stdoutstderr。通常,>会将流直接stdout发送到文件(例如, 的结果printf("hello world\n");发送到stdout)。但是,stderr仍会发送到屏幕,因为它被认为是“需要告知您的异常情况”。

有一种方法可以将 stderr 重定向到文件 - 您可以使用以下(不太直观的)命令执行此操作:

gcc new.c &> myFile

“重定向所有内容”的“bash 简写”在哪里&>。正如 @CharlesDuffy 指出的那样,符合 POSIX 格式的是

gcc new.c > myFile 2>&1

这意味着“编译‘new.c’并发送到stdoutmyFile并且将stderr(2)发送到与stdout&1=“与 stdout 相同的位置”)。

您可以在以下网址找到有关不同重定向的更多详细信息http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.htmlhttp://mywiki.wooledge.org/BashFAQ/055

顺便说一句,如果你想从你的程序中专门发送一些东西到stderr,你可以这样做:

fprintf(stderr, "hello world - this is urgent.\n");

如果你将其包含在程序中,运行该程序并将“正常”输出发送到文件,这仍会出现在控制台上。因此,如果你将上述内容编译为可执行文件urgent,然后输入

./urgent > /dev/null

在控制台上,您的输出将显示在屏幕上。

答案2

因为>重定向仅 stdout,并且错误写入stderr,所以您需要使用下列之一:

gcc new.c &> temp.txt ## redirect both stdout and stderr using bash or zsh only

...或者...

gcc new.c >temp.txt 2>&1 ## redirect both stdout and stderr in any POSIX shell

&>是一个 BASH 扩展,它将stdout和重定向stderr到一个文件;否则,最简单的方法是首先重定向 stdout ( >temp.txt),然后使 stderr (FD 2) 成为 stdout (FD 1 ) 上已重定向文件句柄的副本,如下所示:2>&1

答案3

正如其他人所说,linux 提供了两种不同的输出流:

标准输出或“标准输出”是所有常规输出的位置。
              您可以使用文件描述符来引用它1

标准错误或“标准错误”是用于带外信息的单独流。
              您可以使用文件描述符来引用它2

为什么有两个不同的输出流?考虑一个假想命令管道:

 decrypt $MY_FILE | grep "secret" | sort > secrets.txt

现在假设decrypt命令失败并生成一条错误消息。如果它将该消息发送到stdout,它将发送到管道中,除非它包含单词“secret”,否则您永远不会看到它。因此,您最终会得到一个空的输出文件,不知道出了什么问题。

但是,由于管道仅捕获stdout,因此decrypt命令可以将其错误发送到stderr,然后它们将显示在控制台上。

您可以同时或单独地重定向stdout和:stderr

# Send errors to "errors.txt" and output to "secrets.txt"
# The following two lines are equivalent, as ">" means "1>"
decrypt $MY_FILE 2> errors.txt > secrets.txt
decrypt $MY_FILE 2> errors.txt 1> secrets.txt

您可以将错误重定向到stdout并处理它们,就像它们是正常输出一样:

# The operation "2>&1" means "redirect file descriptor 2 to file
# descriptor 1. So this sends all output from stderr to stdout.
# Note that the order of redirection is important.
decrypt $MY_FILE > errors.txt 2>&1 

# This may be confusing.  It will store the normal output in a file
# and send error messages to stdout, where they'll be captured by 
# the pipe and then sorted.
decrypt $MY_FILE 2>&1 > output.txt | sort

您还可以使用“简写”符号来重定向两个都stdout 和 stderr 到同一个文件:

decrypt $MY_FILE &> output.txt

最后,>运营商将首先截短写入之前,先查看其输出文件。如果您希望附加数据到现有文件,使用>>运算符:

decrypt $MY_FILE 2>> more_errors.txt >> more_secrets.txt
decrypt $MY_FILE >> more_output.txt 2>&1

相关内容