关于stdout / stderr重定向

时间:2010-10-29 08:36:44

标签: c bash

我编写了一个代码来故意获取运行时错误:

int main()
{
 int a=5;
 printf("Hello World\n");
 printf("a=%s\n", a);
}

它给出了:

$ ./error.o
Hello World
Segmentation Fault
$

现在,为了记录运行时错误,我做了:

$ ./error.o > so.txt
$ ./error.o &> soe.txt

但这两个文件都是空的。为什么呢?

编辑:

我实际上正在为远程编译和执行c程序编写脚本。从答案我得到Segmentation Fault不是程序的错误输出。那么,有没有办法捕获输出?此外,该程序只是一个示例,所以我不能添加语句。可以通过重定向以任何其他方式进行行缓冲吗?

3 个答案:

答案 0 :(得分:10)

so.txt为空,因为在崩溃之前stdout没有刷新,因此缓冲的内容丢失了。如果添加:fflush(stdout);在printf命令之间,它将包含预期的文本。

您的soe.txt也缺少消息“Segmentation Fault”,因为它是由shell打印的,而不是由您的程序打印的,因此不是您要重定向的程序输出的一部分。

如果你不能修改代码,你可以通过欺骗程序来打开行缓冲,认为它正在打印到tty。创建脚本error.sh:

#!/bin/sh
./error.o

然后执行chmod a + x error.sh并在Linux上调用它:

script soe.txt -c ./error.sh

或者在OS X上这样:

script soe.txt ./error.sh

确切的输出在某种程度上取决于系统,但可能包含“Hello World”和“Segmentation Fault”。

还要考虑添加适当的#include行并从main返回一个值。

答案 1 :(得分:8)

因为分段错误严重。缓冲区不会被冲洗,你的过程会被暴力关闭。

在没有重定向的情况下运行时看到文本的原因是标准输出是行缓冲的(ISO C要求仅在可以确定设备不是交互式设备时才使用完全缓冲)。换句话说,它会在看到换行符时刷新,并且无效的解引用之前发生。

但是因为文件输出不是行缓冲的,所以当程序的Universe从它下面被挖出时,信息仍在等待发送出来。

虽然对此的支持是实现定义的,但您可以使用setvbuf模式使用_IOLBF将特定文件句柄设置为行缓冲,如:

setvbuf (stdout, NULL, _IOLBF, BUFSIZ);

main()的开头 - 它可以节省大量的输入,而不是每个输出行fflush

答案 2 :(得分:3)

我认为应该这样做:

echo ./error.o | sh > error.txt
相关问题