简体   繁体   English

关于stdout / stderr重定向

[英]About stdout/stderr redirections

I wrote a code to get a runtime error intentionally: 我编写了一个代码来故意获取运行时错误:

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

It gives: 它给:

$ ./error.o
Hello World
Segmentation Fault
$

Now, to record the runtime errors, I do: 现在,为了记录运行时错误,我做:

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

But both the files are empty. 但这两个文件都是空的。 Why? 为什么?

EDIT: 编辑:

I'm actually writing a script for remote compilation and execution of ac program. 我实际上正在编写一个用于远程编译和执行ac程序的脚本。 From the answers I get that Segmentation Fault is not the program's error output. 从答案我得到Segmentation Fault不是程序的错误输出。 So, is there a way to capture that output? 那么,有没有办法捕获输出? Also, the program is just a sample, so I can't add the statements. 此外,该程序只是一个示例,所以我不能添加语句。 Can line-buffering be done any other way with redirections? 可以通过重定向以任何其他方式进行行缓冲吗?

so.txt is empty because stdout didn't get flushed before the crash so the buffered content was lost. so.txt是空的,因为stdout在崩溃之前没有刷新,因此缓冲的内容丢失了。 If you add: fflush(stdout); 如果添加:fflush(stdout); between the printf-commands, it will contain the expected text. 在printf命令之间,它将包含预期的文本。

Your soe.txt is missing also the the message "Segmentation Fault" because it was printed by the shell, not by your program and thus wasn't part of your program's output that was to be redirected. 您的soe.txt也缺少消息“Segmentation Fault”,因为它是由shell打印的,而不是由您的程序打印的,因此不是您要重定向的程序输出的一部分。

If you can't modify the code, you can turn on line buffering by fooling the program to think it's printing to a tty. 如果你不能修改代码,你可以通过欺骗程序来打开行缓冲,认为它打印到tty。 Create the script error.sh: 创建脚本error.sh:

#!/bin/sh
./error.o

Then do chmod a+x error.sh and call it like this on Linux: 然后执行chmod a + x error.sh并在Linux上调用它:

script soe.txt -c ./error.sh

Or like this on OS X: 或者在OS X上这样:

script soe.txt ./error.sh

The exact output is somewhat system-dependent but will probably contain both "Hello World" and "Segmentation Fault". 确切的输出在某种程度上取决于系统,但可能包含“Hello World”和“Segmentation Fault”。

Also consider adding appropriate #include lines and returning a value from main. 还要考虑添加适当的#include行并从main返回一个值。

Because a segmentation fault is serious . 因为分段错误很严重 Buffers don't get flushed, your process just gets shut down violently. 缓冲区不会被冲洗,您的过程会被猛烈关闭。

The reason you see the text when you run without redirection is that standard output is line buffered (ISO C mandates that full buffering is used only if the device can be determined not to be an interactive one). 在没有重定向的情况下运行时看到文本的原因是标准输出是行缓冲的(ISO C要求仅在可以确定设备不是交互式设备时才使用完全缓冲)。 In other words, it will flush whenever it sees a newline, and that happens before your invalid de-referencing. 换句话说,它会在看到换行符时刷新,并且无效的解引用之前发生。

But because the file output is not line-buffered, the information is still waiting to be sent out when your program's universe is yanked out from under it. 但是因为文件输出不是行缓冲的,所以当程序的Universe从它下面被拉出时,信息仍然在等待发送出去。

Although support for this is implementation-defined, you can set a specific file handle to be line buffered by using setvbuf with the _IOLBF mode, something like: 虽然对此的支持是实现定义的,但您可以使用带有_IOLBF模式的setvbuf将特定文件句柄设置为行缓冲,例如:

setvbuf (stdout, NULL, _IOLBF, BUFSIZ);

at the start of main() - it saves a substantial amount of typing over having to fflush every output line. main()的开头 - 它可以节省大量的输入,而不必每次输出都是fflush

我认为应该这样做:

echo ./error.o | sh > error.txt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM