简体   繁体   中英

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. From the answers I get that Segmentation Fault is not the program's error output. 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. If you add: fflush(stdout); between the printf-commands, it will contain the expected text.

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.

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. Create the script error.sh:

#!/bin/sh
./error.o

Then do chmod a+x error.sh and call it like this on Linux:

script soe.txt -c ./error.sh

Or like this on OS X:

script soe.txt ./error.sh

The exact output is somewhat system-dependent but will probably contain both "Hello World" and "Segmentation Fault".

Also consider adding appropriate #include lines and returning a value from 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). 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.

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:

setvbuf (stdout, NULL, _IOLBF, BUFSIZ);

at the start of main() - it saves a substantial amount of typing over having to fflush every output line.

我认为应该这样做:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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