关于stdout/stderr重定向

lal*_*lli 8 c bash

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

int main()
{
 int a=5;
 printf("Hello World\n");
 printf("a=%s\n", a);
}
Run Code Online (Sandbox Code Playgroud)

它给:

$ ./error.o
Hello World
Segmentation Fault
$
Run Code Online (Sandbox Code Playgroud)

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

$ ./error.o > so.txt
$ ./error.o &> soe.txt
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

jjr*_*jrv 10

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

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

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

#!/bin/sh
./error.o
Run Code Online (Sandbox Code Playgroud)

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

script soe.txt -c ./error.sh
Run Code Online (Sandbox Code Playgroud)

或者在OS X上这样:

script soe.txt ./error.sh
Run Code Online (Sandbox Code Playgroud)

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

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


pax*_*blo 7

因为分段错误很严重.缓冲区不会被冲洗,您的过程会被猛烈关闭.

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

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

虽然这种支持是实现定义的,你可以设置一个特定的文件句柄通过使用行缓冲setvbuf_IOLBF模式,喜欢的东西:

setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
Run Code Online (Sandbox Code Playgroud)

在开始时main()- 它节省了大量的输入,而不是fflush每个输出线.